News for hackers. Stuff that matters.
Re:It's not what programming languages do, it's what they sh... by js8 on Friday March 27, 2020 @08:31AM (#22702322)
For logging, you can use unsafePerformIO. Of course, you would call it inside a special function that can do logging. In fact, there are functions in Debug.Trace that do exactly that (to standard output).

Similarly, I used unsafePerformIO (again put into a convenient function) to save a checkpoint data in a large computation. The computation is defined pure, but it calls the function to checkpoint, which does in fact IO under the covers.

Remember, type safety is there to help you. As long as the function performing the I/O doesn't affect the outcome of the computation, everything is safe.

Re:It's not what programming languages do, it's what they sh... by ghostwriter on Friday March 27, 2020 @10:02AM (#22702877)
> As long as the function performing the I/O doesn't affect the outcome of the computation, everything is safe.

except it's not! Your IO action may not affect the outcome of the computation but it may launch the missiles in background, which changes everything. The less contrived example would be - "computation is fine and is not affected, yet we have our [production cluster deleted / disk space run out / money sent to wrong recepients] by the IO action".

Re:It's not what programming languages do, it's what they sh... by nybble41 on Friday March 27, 2020 @06:34PM (#22707524)
Despite the name, unsafePerformIO isn't automatically akin to undefined behavior in C. It can cause undefined behavior if misused, the most obvious example being the creation of polymorphic I/O reference objects which act like unsafeCoerce—but that would be affecting the outcome of the computation. If the value returned from unsafePerformIO is a pure function of the inputs then the only remaining risk is that any side effects may occur more than once or not at all depending on how the pure code is evaluated. As long as you're okay with that there isn't really any issue with using something like Debug.Trace for its intended purpose, debugging.

There are better ways to handle logging, of course—you generally want your log entries to be deterministic, and the ability to produce log entries (as opposed to arbitrary I/O actions) should be reflected in the types.

Re:It's not what programming languages do, it's what they sh... by gowld on Friday March 27, 2020 @11:31AM (#22703689)
Debug.Trace doesn't launch missiles or delete clusters or send money. It might run you out of disk space, but so can safe IO.
Re:It's not what programming languages do, it's what they sh... by marcosdumay on Friday March 27, 2020 @09:34AM (#22702677)
Honestly, that will depend on what exactly both you and the GP are calling "logging".

Usually "logging" is semantically relevant, and it better reflect on the return type. But well, it's pretty useless to log the execution of pure code anyway.

I agree that GP seems to be talking about print-debugging (one doesn't go changing his mind about semantically relevant logging), so everything on your comment is on the spot, but generalizing this can lead to confusion.

Re:It's not what programming languages do, it's what they sh... by js8 on Friday March 27, 2020 @10:17AM (#22702994)
Standard functional programming methods apply, in this case you would use inversion of control to limit the access to I/O.

If you need to do "semantically relevant" logging from a pure function, just create a pure function to process the semantic relevant part to something generic (like a Text), and call the simple unsafe logging function on the generic result.

Re:It's not what programming languages do, it's what they sh... by dropofwill on Friday March 27, 2020 @02:14PM (#22705272)
Thinking about the systems I work with I can only think of a few cases where logging is semantically relevant (the way I understand it).

One is replaying critical failed requests when a downstream was offline and the other is gathering tracking statistics from apache access logs.

Everything else I would classify as diagnostic, wondering if you would consider that semantic as well.

Re:It's not what programming languages do, it's what they sh... by marcosdumay on Friday March 27, 2020 @05:47PM (#22707209)
To clarify it, what I mean by semantically relevant is if it is on the user requirements. It's not semantically relevant if it's there just to make the developer's life easier. So, it seems we are using the same definition.

Every kind of software has some error log, long lived servers tend to have some usage log too, databases tend to have journaling logs, and distributed computing tends to have a retry log. There are other kinds of them, like all those lines a compiler outputs when it tries to work on a program, or the ones a hardware programmer shows while working. Every one of those are there for the user.

Re:It's not what programming languages do, it's what they sh... by cjfd on Friday March 27, 2020 @08:37AM (#22702354)
Okay, that does sound like a workable solution.