Coding: Fleeting Thoughts

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

User avatar
Xanthir
My HERO!!!
Posts: 5426
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Coding: Fleeting Thoughts

Postby Xanthir » Tue Jun 07, 2016 10:06 pm UTC

Agree, but I'd go further. It's not enough to just explain what Reader is, you have to show its implementation, too - I was confused as *heck* by Reader until I realized how simple it was. (Some article finally outright said "Reader is just Function, but given a different name to express more precise semantics", and a lightbulb clicked in my head.)
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

User avatar
headprogrammingczar
Posts: 3072
Joined: Mon Oct 22, 2007 5:28 pm UTC
Location: Beaming you up

Re: Coding: Fleeting Thoughts

Postby headprogrammingczar » Tue Jun 07, 2016 11:48 pm UTC

Xanthir wrote:IO *is* implemented as a container, though. IO and Reader are *literally the exact same thing*, and both of them are *literally the exact same thing* as Function. In functor form, they're all a container holding a function that you'll evaluate later when you want to extract the "value" from them. The only reason they're distinguished is because there are several distinct semantics that can all be represented by the same internal representation, and giving things good names that represent their usage is important.


I assume you're referring to the RealWorld definition of IO? That definition can't support things like concurrency because it would require the RealWorld value to be mutable, so it can't be a valid definition. A better definition of IO would be the CPS one, which is about as un-containerlike as you can get and still has some problems (namely that you need an open data type to implement the FFI). GHC uses something similar to the RealWorld definition internally:

Code: Select all

newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #))
type role IO representational


However here's where things get weird:

Code: Select all

-- | @State\#@ is the primitive, unlifted type of states.  It has
--         one type parameter, thus @State\# RealWorld@, or @State\# s@,
--         where s is a type variable. The only purpose of the type parameter
--         is to keep different state threads separate.  It is represented by
--         nothing at all.

data State# s

-- | @RealWorld@ is deeply magical.  It is /primitive/, but it is not
--         /unlifted/ (hence @ptrArg@).  We never manipulate values of type
--         @RealWorld@; it\'s only used in the type system, to parameterise @State\#@.

data RealWorld


So if you strip down those types it becomes IO a = Void -> (# Void, a #). And then the role annotation happens, which says that 'a' and 'IO a' have the same representation. So IO a = a. The RealWorld that ostensibly gets passed around is just to make sure things are ordered, and no value or even placeholder for a value ever gets compiled into a program. An amusing consequence of this is that unsafePerformIO = id. That's right folks, GHC Haskell is impure! (technically it has to be simply by the presence of unsafePerformIO to begin with)

Anyway IO is decidedly not the same as Reader, but something far more interesting. This isn't really in response to anything, I just saw it as an excuse to talk about a weird implementation detail and correct a misunderstanding. The only useful mental model of IO for reasoning about code is to consider it abstract anyway.
<quintopia> You're not crazy. you're the goddamn headprogrammingspock!
<Weeks> You're the goddamn headprogrammingspock!
<Cheese> I love you

User avatar
Xanthir
My HERO!!!
Posts: 5426
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Coding: Fleeting Thoughts

Postby Xanthir » Wed Jun 08, 2016 12:17 am UTC

Right, unsafePerformIO is just "run the function inside of the IO and return the result". The function inside of the IO is just something that takes no arguments and potentially has side-effects; it exists just to delay the side-effects until either the runtime is ready to do them or you're ready to take the impurity hit.

(You're right that it's technically not identical to Reader, because Reader takes an argument for its "extract the value" method. Excepting that, they are identical in implementation, tho. Reader *is* identical to Function, tho, because that's all it is, a function.)

Whatever voodoo you just described for the particular implementation in some Haskell engine is irrelevant and harmful for actually learning what IO is and how it works. Yeah, things get more complicated when you start addressing stuff like concurrency; that's irrelevant for teaching unless you're working thru advanced topics.

(Even talking about IO concerning some sort of "real world" is, I think, mildly harmful. It must be stressed that that's just the *metaphorical* interpretation of IO; in reality it's just a container holding a 0-arg function that might have side-effects, and when you .map() over it, it just composes your function with the one it currently holds and hands back a new IO with the result.)
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

User avatar
headprogrammingczar
Posts: 3072
Joined: Mon Oct 22, 2007 5:28 pm UTC
Location: Beaming you up

Re: Coding: Fleeting Thoughts

Postby headprogrammingczar » Wed Jun 08, 2016 7:08 pm UTC

You're still really hung up on this container idea, as if IO always has something inside it. For purposes of reasoning about it, it's abstract. It's a mystery cloud of who-knows. It may contain something, it may not. Maybe it all gets lifted out and at runtime there's no IO values anywhere! GHC's voodoo nonsense and "IO is a container" nonsense are both equally irrelevant.
<quintopia> You're not crazy. you're the goddamn headprogrammingspock!
<Weeks> You're the goddamn headprogrammingspock!
<Cheese> I love you

User avatar
Xanthir
My HERO!!!
Posts: 5426
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Coding: Fleeting Thoughts

Postby Xanthir » Wed Jun 08, 2016 9:29 pm UTC

Yes, my point that I keep hammering on is that almost all tutorials talk about IO in the "purposes of reasoning about" sense, which is *incredibly damaging* to actually *understanding* functors. It makes them seem like magical, impossible-to-understand abstractions that only crazy languages like Haskell can support and that you need a math degree to fully grasp.

When actually they're just a useful abstraction that's trivial to understand if people would describe them in concrete terms once in a while.

Languages can do voodoo to some privileged set of special ones for efficiency, sure. That doesn't mean it should be impossible to understand how to implement an IO functor in Javascript to help you rein in side-effects, but that's exactly what happens when you only discuss IO as being "the thing that does sequencing" or "a container holding the Real World inside of it".

Same with Reader - I was just incredibly confused about what it actually did and how it worked, because nothing actually explained its mechanisms, just abstract metaphorical stuff like "Represents a computation, which can read values from a shared environment, pass values from function to function, and execute sub-computations in a modified environment." (from the Haskell wiki). This wasn't helped by the fact that the Reader + do-notation combination purposely looks *incredibly imperative*, like a query-and-response mechanism, when it's nothing of the sort. When it was finally explained that it's just a renamed Function, so that you can write code that queries some "environment variable" and only actually supply the environment variable later (in other words, it defaults to being the id function), I was suddenly enlightened.
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

User avatar
headprogrammingczar
Posts: 3072
Joined: Mon Oct 22, 2007 5:28 pm UTC
Location: Beaming you up

Re: Coding: Fleeting Thoughts

Postby headprogrammingczar » Thu Jun 09, 2016 12:43 am UTC

Reader is completely different, because it actually has an approachable implementation. Maybe you're hung up on trying to make IO a good example to learn with, when in reality it's one of the worst and it can't really be fixed by calling IO a container. It's a lie (which isn't inherently bad, some lies are necessary to teach something well), but it's a lie which opens up some rather direly misinformed trains of thought. The one I see constantly in #haskell is that someone will learn monads or functors as containers, and then ask how to take things out of them. Every time it takes an hour or two to convince them it's impossible, and when they finally get past those misconceptions they are surprised by how simple Monad is:

Code: Select all

class Applicative m => Monad m where
    (>>=) :: m a -> (a -> m b) -> m b

    return :: a -> m a
    return = pure


It's an easy trap to fall into, and one that directly creates the tutorials that have confused you in the past. Notice that you weren't able to learn Reader properly until someone pointed out the definition to you.
<quintopia> You're not crazy. you're the goddamn headprogrammingspock!
<Weeks> You're the goddamn headprogrammingspock!
<Cheese> I love you

User avatar
Xanthir
My HERO!!!
Posts: 5426
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Coding: Fleeting Thoughts

Postby Xanthir » Thu Jun 09, 2016 4:11 am UTC

Notice that you weren't able to learn Reader properly until someone pointed out the definition to you.

No, the *definition* I'd seen plenty of times. I'd read over the Haskell wiki definition of it several times, and saw several tutorials giving servicable definitions.

It was the *implementation* of it that finally made it click for me.

Reader is completely different, because it actually has an approachable implementation. Maybe you're hung up on trying to make IO a good example to learn with, when in reality it's one of the worst and it can't really be fixed by calling IO a container. It's a lie (which isn't inherently bad, some lies are necessary to teach something well), but it's a lie which opens up some rather direly misinformed trains of thought.

Again, finally seeing it as a container (rather than as a hand-wavey metaphor about "sequencing computations" or "contains the Real World") is what allowed me to finally understand what the hell IO was and how it worked.

It sounds like maybe a more abstract way of thinking about it was sufficient for you to understand these things? It definitely wasn't for me - I need to know how to implement something before I *really* understand it - and from my personal experience, it's not sufficient for many experienced programmers. Many of my coworkers (at Google, all very skilled) have talked about monads as still being intrinsically confusing/mysterious, and were surprised when I said they were actually super-simple and offered to explain it to them. Hearing a decent explanation of them in terms of actual implementation details often left them suspicious; they couldn't believe it was actually that simple, considering how much obfuscation common explanations had provided.
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

User avatar
headprogrammingczar
Posts: 3072
Joined: Mon Oct 22, 2007 5:28 pm UTC
Location: Beaming you up

Re: Coding: Fleeting Thoughts

Postby headprogrammingczar » Thu Jun 09, 2016 10:13 am UTC

Xanthir wrote:
Notice that you weren't able to learn Reader properly until someone pointed out the definition to you.

No, the *definition* I'd seen plenty of times. I'd read over the Haskell wiki definition of it several times, and saw several tutorials giving servicable definitions.

It was the *implementation* of it that finally made it click for me.


What's the difference between the definition and implementation? They're both the same for any non-abstract ADT.

Code: Select all

data Reader r a = Reader (r -> a)


Edit: I see now. What you were reading on the wiki was not the definition, but some indirect analogy which doesn't really teach anything (the wiki is an awful learning resource). In almost all cases (with the exception being abstract stuff like IO), definition and implementation are exactly the same thing.
<quintopia> You're not crazy. you're the goddamn headprogrammingspock!
<Weeks> You're the goddamn headprogrammingspock!
<Cheese> I love you

User avatar
Xanthir
My HERO!!!
Posts: 5426
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Coding: Fleeting Thoughts

Postby Xanthir » Thu Jun 09, 2016 8:44 pm UTC

The wiki is what comes up when you search for these things, and it gets linked often. ^_^

(Glass houses here tho - W3Schools comes up highly in search results for web stuff, and it's a trash fire.)
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

User avatar
ucim
Posts: 6896
Joined: Fri Sep 28, 2012 3:23 pm UTC
Location: The One True Thread

Re: Coding: Fleeting Thoughts

Postby ucim » Thu Jun 09, 2016 11:00 pm UTC

Xanthir wrote:W3Schools comes up highly in search results for web stuff, and it's a trash fire.
Yeah, what's with that? How do they get rated so highly (by search engines, who should know better by now)?

Jose
Order of the Sillies, Honoris Causam - bestowed by charlie_grumbles on NP 859 * OTTscar winner: Wordsmith - bestowed by yappobiscuts and the OTT on NP 1832 * Ecclesiastical Calendar of the Order of the Holy Contradiction * Heartfelt thanks from addams and from me - you really made a difference.

User avatar
Flumble
Yes Man
Posts: 2266
Joined: Sun Aug 05, 2012 9:35 pm UTC

Re: Coding: Fleeting Thoughts

Postby Flumble » Thu Jun 09, 2016 11:14 pm UTC

We should build our own search engine without w3schools, but with blackjack and hookers.

Huh, I never noticed: the internet is largely blackjack and hookers, in the form of gambling and porn. So did Bender create it?

User avatar
phlip
Restorer of Worlds
Posts: 7573
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: Coding: Fleeting Thoughts

Postby phlip » Thu Jun 09, 2016 11:19 pm UTC

Once upon a time, Google had an option to hide results from domains of your choice, so you could hide w3schools results and be at peace. But they removed that option years ago.

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

commodorejohn
Posts: 1201
Joined: Thu Dec 10, 2009 6:21 pm UTC
Location: Placerville, CA
Contact:

Re: Coding: Fleeting Thoughts

Postby commodorejohn » Fri Jun 10, 2016 12:50 am UTC

phlip wrote:Once upon a time, Google had an option to hide results from domains of your choice, so you could hide w3schools results and be at peace. But they removed that option years ago.

Eh? I'm plenty happy to bag on Google for making their things worse (dammit, stop clogging up my YouTube search results with playlists and channels that have the videos you already showed me!) but a search for html tag list -site:w3schools.com still works exactly as it used to, at least on my end.
"'Legacy code' often differs from its suggested alternative by actually working and scaling."
- Bjarne Stroustrup
www.commodorejohn.com - in case you were wondering, which you probably weren't.

User avatar
Xanthir
My HERO!!!
Posts: 5426
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Coding: Fleeting Thoughts

Postby Xanthir » Fri Jun 10, 2016 1:56 am UTC

I think he means blacklisting a domain once, so it never shows up again.
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

commodorejohn
Posts: 1201
Joined: Thu Dec 10, 2009 6:21 pm UTC
Location: Placerville, CA
Contact:

Re: Coding: Fleeting Thoughts

Postby commodorejohn » Fri Jun 10, 2016 2:41 am UTC

Ah.
"'Legacy code' often differs from its suggested alternative by actually working and scaling."
- Bjarne Stroustrup
www.commodorejohn.com - in case you were wondering, which you probably weren't.

User avatar
phlip
Restorer of Worlds
Posts: 7573
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: Coding: Fleeting Thoughts

Postby phlip » Fri Jun 10, 2016 12:14 pm UTC

Yeah, there used to be this thing where if you clicked a link and then clicked back to return to the results, there'd be a couple of options underneath the search result, one of which was "stop showing results from w3schools.com", which applied until your preferences cookie expired (or until they removed the feature).

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

lorb
Posts: 405
Joined: Wed Nov 10, 2010 10:34 am UTC
Location: Austria

Re: Coding: Fleeting Thoughts

Postby lorb » Fri Jun 10, 2016 1:40 pm UTC

also the + and - operators are not strict like they used to be. sometimes the algo at google will determine that you don't know what you are doing and ignore them.
Please be gracious in judging my english. (I am not a native speaker/writer.)
http://decodedarfur.org/

User avatar
Whizbang
The Best Reporter
Posts: 2238
Joined: Fri Apr 06, 2012 7:50 pm UTC
Location: New Hampshire, USA

Re: Coding: Fleeting Thoughts

Postby Whizbang » Fri Jun 10, 2016 1:51 pm UTC

My 8yo son's CFT: "Hey, Dad, do you think we could make a game on the computer?"

Me: "Sure! That'd be a lot of fun. I've been wanting to get you into coding for a while. We'll make it a summer project."

Son: "No. I mean, can we make it before the last day of school (Monday) so I can show my friends?"

Me: "... Uh. Ok. Sure. We can make a simple game like pong or snake or something."

Son: "I want it to be a maze. And Brian says it can't be cartoon-y. And can we make it so my friends can choose a boy or girl? And can we see who has the highest score?"

Me: (Desperately wanting to do this with him) "Well... We can't do all of that. Let's Google for some simple Javascript games and see if there is anything you like that we can do this weekend."

I foresee disappointment for both him and me.

commodorejohn
Posts: 1201
Joined: Thu Dec 10, 2009 6:21 pm UTC
Location: Placerville, CA
Contact:

Re: Coding: Fleeting Thoughts

Postby commodorejohn » Fri Jun 10, 2016 2:22 pm UTC

lorb wrote:also the + and - operators are not strict like they used to be. sometimes the algo at google will determine that you don't know what you are doing and ignore them.

Yeah, this is one of the big things that irks me about what they've done with the search engine. Though I think it's still strict as far as domains go.
"'Legacy code' often differs from its suggested alternative by actually working and scaling."
- Bjarne Stroustrup
www.commodorejohn.com - in case you were wondering, which you probably weren't.

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Fri Jun 10, 2016 2:23 pm UTC

Whizbang wrote:My 8yo son's CFT: "Hey, Dad, do you think we could make a game on the computer?"

[...]

I foresee disappointment for both him and me.


Try UnrealEngine 4. Allows you to do quite a lot without actually writing code (blueprints they call it, basically visual programming).

Have a look at this for example: https://docs.unrealengine.com/latest/IN ... index.html
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
Flumble
Yes Man
Posts: 2266
Joined: Sun Aug 05, 2012 9:35 pm UTC

Re: Coding: Fleeting Thoughts

Postby Flumble » Fri Jun 10, 2016 4:02 pm UTC

I concur, unreal's blueprints are like gamemaker's (or scratch's or snap!'s) drag&drop on steroids. Or any dataflow language (like blender's) on a less extreme drug.
Unity is also a good starting point, assuming that there are standard motion assets available/included.
You can easily build a (3D!) maze in either using the included editor and free assets from the web or the unity store.

There's also RPGMaker, but that's mostly for making RPGs, not maze games. And I have no idea how easy/versatile their programming language is.

korona
Posts: 495
Joined: Sun Jul 04, 2010 8:40 pm UTC

Re: Coding: Fleeting Thoughts

Postby korona » Sat Jun 11, 2016 11:10 am UTC

Xanthir wrote:Again, finally seeing it as a container (rather than as a hand-wavey metaphor about "sequencing computations" or "contains the Real World") is what allowed me to finally understand what the hell IO was and how it worked.

I always think of IO as "IO is what the whole program in languages with side-effects is". I don't know if explaining it as a nullary function is that good because there are no nullary functions in a Haskell/math sense. IO also cannot be implemented in pure Haskell, right? There always has to be some "run this IO object called main" magic. Also note that main is a constant and not a function in Haskell. It is not even possible to define what "running the IO object" means in Haskell itself. You need some meta language (e.g. English) to do that.

User avatar
Xanthir
My HERO!!!
Posts: 5426
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Coding: Fleeting Thoughts

Postby Xanthir » Sat Jun 11, 2016 4:34 pm UTC

korona wrote:I always think of IO as "IO is what the whole program in languages with side-effects is".

That's more of the hand-waving metaphorical nonsense that makes it so hard to understand. >_< That sentence you just wrote gives me *zero* insight into how IO works or how I might implement it. It *sounds* like I have to write an entire language to implement IO, or maybe build it deeply into the language somehow?

I don't know if explaining it as a nullary function is that good because there are no nullary functions in a Haskell/math sense. IO also cannot be implemented in pure Haskell, right? There always has to be some "run this IO object called main" magic. Also note that main is a constant and not a function in Haskell. It is not even possible to define what "running the IO object" means in Haskell itself. You need some meta language (e.g. English) to do that.

Yeah, Haskell's semantic that a function call === its return value makes IO particularly difficult to understand in Haskell.

In, say, JS, IO is trivial to write and fairly easy to understand:

Code: Select all

class IO {
   constructor(nonIdempotentFunction) {
      this.__getVal__ = nonIdempotentFunction;
      return this;
   }
   unsafePerformIO() {
      return this.__getVal__();
   }
   map(fn) {
      return new IO(()=>fn(this.__getVal__()));
   }
   lift(val) {
      return new IO(()=>val);
   }
   join() {
      return new IO(()=>this.__getVal__().__getVal__());
   }
   bind(fn) {
      return this.map(fn).join();
      // or
      // return new IO(()=>fn(this.__getVal__()).__getVal__());
      // if you want to reduce object churn and callstack depth
   }
}


(Code is untested but should work.)

The only difficulty here is wrapping your head around deferring all of the actions you're performing by wrapping them in another nullary function. Once you get that, this is otherwise a bog-standard, super-trivial functor.
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

korona
Posts: 495
Joined: Sun Jul 04, 2010 8:40 pm UTC

Re: Coding: Fleeting Thoughts

Postby korona » Sat Jun 11, 2016 6:06 pm UTC

JS kind of already has IO, it's just called Promise :D.

User avatar
Xanthir
My HERO!!!
Posts: 5426
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Coding: Fleeting Thoughts

Postby Xanthir » Sat Jun 11, 2016 8:26 pm UTC

No? Promise is a completely different functor with unrelated semantics (it's the "asynchronous Maybe"). It's just also a fairly simple "container holding a value" functor that defers work a little bit.
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

User avatar
headprogrammingczar
Posts: 3072
Joined: Mon Oct 22, 2007 5:28 pm UTC
Location: Beaming you up

Re: Coding: Fleeting Thoughts

Postby headprogrammingczar » Sat Jun 11, 2016 9:06 pm UTC

It's sort of cheating to implement IO in a language that's already impure.
<quintopia> You're not crazy. you're the goddamn headprogrammingspock!
<Weeks> You're the goddamn headprogrammingspock!
<Cheese> I love you

korona
Posts: 495
Joined: Sun Jul 04, 2010 8:40 pm UTC

Re: Coding: Fleeting Thoughts

Postby korona » Sat Jun 11, 2016 9:27 pm UTC

Xanthir wrote:No? Promise is a completely different functor with unrelated semantics (it's the "asynchronous Maybe"). It's just also a fairly simple "container holding a value" functor that defers work a little bit.

If you ignore the reject path of a promise (that makes Promises more like Either than like Maybe) then promises are equivalent to IO (apart from the fact that you can "cheat" and do impure things in a function passed to >>= aka .then). Asynchronous vs. synchronous are imperative concepts that make no sense from a pure functional POV. Implementing IO as a promise (i.e. as a 'fairly simple "container holding a value" functor that defers work a little bit.') inside a Haskell compiler (not in Haskell itself of course) is perfectly viable.

User avatar
Xanthir
My HERO!!!
Posts: 5426
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Coding: Fleeting Thoughts

Postby Xanthir » Sun Jun 12, 2016 6:42 pm UTC

headprogrammingczar wrote:It's sort of cheating to implement IO in a language that's already impure.

??? Why? What makes it "cheating", and what part of my implementation utilizes impurity to cheat?

Like, do you think that, because impurity exists, IO can't even be useful in JS? I assure you that it can! (For example, there's a library called "FastDOM" that helps authors out by forcing DOM read and write operations to be batched separately. This can be turned into an actual IO monad without much difficulty.)

korona wrote:If you ignore the reject path of a promise (that makes Promises more like Either than like Maybe)

Sure, a lot of the time the distinction between Maybe and Either is irrelevant; it's just a matter of how much effort the producer wants to put into communicating the reason for a failure. I was using Maybe as a shorthand here.

then promises are equivalent to IO (apart from the fact that you can "cheat" and do impure things in a function passed to >>= aka .then). Asynchronous vs. synchronous are imperative concepts that make no sense from a pure functional POV. Implementing IO as a promise (i.e. as a 'fairly simple "container holding a value" functor that defers work a little bit.') inside a Haskell compiler (not in Haskell itself of course) is perfectly viable.

No, they're still completely different. Functions that return promises will start doing their work immediately; this work can easily be non-idempotent, and you have no control over the timing. You can just start operating on the "value inside of it" immediately.

Just because something is capable of being non-idempotent does not automatically make it IO; IO does not have a monopoly on that concept. IO is about collecting non-idempotent operations and executing them at a well-defined time and in a well-controlled order; either when you call unsafePerformIO() on it, or when the runtime does while executing your program. This is not what Promises do.
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

korona
Posts: 495
Joined: Sun Jul 04, 2010 8:40 pm UTC

Re: Coding: Fleeting Thoughts

Postby korona » Sun Jun 12, 2016 9:46 pm UTC

Does Haskell really specify the timing of IO execution at all? AFAIK it does not (so IO could be implemented as Promise) but if it does then you're right of course.

EDIT: Of course just creating an IO object does not run it immediately but that results more from the pure vs. impure difference than from the Promise vs. IO conceptual difference.

User avatar
headprogrammingczar
Posts: 3072
Joined: Mon Oct 22, 2007 5:28 pm UTC
Location: Beaming you up

Re: Coding: Fleeting Thoughts

Postby headprogrammingczar » Sun Jun 12, 2016 11:07 pm UTC

Xanthir wrote:
headprogrammingczar wrote:It's sort of cheating to implement IO in a language that's already impure.

??? Why? What makes it "cheating"


Because if you translate what you did to Haskell, what you really have there is Identity. Specifically, only in a language where side effects exist outside IO can you pass nonIdempotentFunction to the constructor to begin with. That was more of a cheeky comment than a criticism of your code though. :P
<quintopia> You're not crazy. you're the goddamn headprogrammingspock!
<Weeks> You're the goddamn headprogrammingspock!
<Cheese> I love you

User avatar
jestingrabbit
Factoids are just Datas that haven't grown up yet
Posts: 5967
Joined: Tue Nov 28, 2006 9:50 pm UTC
Location: Sydney

Re: Coding: Fleeting Thoughts

Postby jestingrabbit » Mon Jun 13, 2016 8:00 am UTC

Nice choice of modula arithmetic Java. Zero out of ten. Go back and get it right this time...
ameretrifle wrote:Magic space feudalism is therefore a viable idea.

User avatar
Yakk
Poster with most posts but no title.
Posts: 11129
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: Coding: Fleeting Thoughts

Postby Yakk » Mon Jun 13, 2016 11:13 am UTC

jestingrabbit wrote:Nice choice of modula arithmetic Java. Zero out of ten. Go back and get it right this time...

That is the fault of `a/b`. Obviously `a = a/b + a%b` (anything else is insanity), so the fact that `a/-b = -(a/b)` means `a%-b = -(a%b)`
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
jestingrabbit
Factoids are just Datas that haven't grown up yet
Posts: 5967
Joined: Tue Nov 28, 2006 9:50 pm UTC
Location: Sydney

Re: Coding: Fleeting Thoughts

Postby jestingrabbit » Mon Jun 13, 2016 11:38 am UTC

Okay, but now explain why Calendar.get(Calendar.DAY_OF_WEEK) ranges from 1 to 7 and Calendar.getTime.getDay() ranges from 0 to 6.
ameretrifle wrote:Magic space feudalism is therefore a viable idea.

Ubik
Posts: 1016
Joined: Thu Oct 18, 2007 3:43 pm UTC

Re: Coding: Fleeting Thoughts

Postby Ubik » Mon Jun 13, 2016 11:43 am UTC

They obviously wanted to be consistent with the inconsistency of mixed zero-based and one-based indexes of years, months and days of month.

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Mon Jun 13, 2016 3:36 pm UTC

jestingrabbit wrote:Okay, but now explain why Calendar.get(Calendar.DAY_OF_WEEK) ranges from 1 to 7 and Calendar.getTime.getDay() ranges from 0 to 6.


Boolean.getBoolean() is my favorite part of the Java API.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

commodorejohn
Posts: 1201
Joined: Thu Dec 10, 2009 6:21 pm UTC
Location: Placerville, CA
Contact:

Re: Coding: Fleeting Thoughts

Postby commodorejohn » Mon Jun 13, 2016 4:05 pm UTC

The method list for the Boolean class pretty much tells you everything you need to know about Java right there.
"'Legacy code' often differs from its suggested alternative by actually working and scaling."
- Bjarne Stroustrup
www.commodorejohn.com - in case you were wondering, which you probably weren't.

EvanED
Posts: 4331
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI
Contact:

Re: Coding: Fleeting Thoughts

Postby EvanED » Mon Jun 13, 2016 7:11 pm UTC

Pretty sure I've posted this before, but my absolute favorite DailyWTF is this "false detector":

Code: Select all

public boolean checkFalse(Boolean bool)
{
  if (bool.booleanValue() == Boolean.FALSE.booleanValue())
  {
    return Boolean.FALSE.booleanValue();
  }
  else
  {
    return Boolean.TRUE.booleanValue();
  }
}


This is is like an onion of WTFs.

User avatar
Xanthir
My HERO!!!
Posts: 5426
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Coding: Fleeting Thoughts

Postby Xanthir » Mon Jun 13, 2016 8:38 pm UTC

korona wrote:Does Haskell really specify the timing of IO execution at all? AFAIK it does not (so IO could be implemented as Promise) but if it does then you're right of course.

EDIT: Of course just creating an IO object does not run it immediately but that results more from the pure vs. impure difference than from the Promise vs. IO conceptual difference.

I have no idea if Haskell specifies timing or not, but at least in practice it's required to; IO is a source of uncontrolled non-idempotency by definition, so if it ran just whenever it wanted, it would do (even more) unpredictable things. Coordinating the timing of your non-idempotency is the entire point of IO, otherwise it's *worse* than an impure language (at least there you know when non-idempotent things will happen - when you call the impure function!).

headprogrammingczar wrote:
Xanthir wrote:
headprogrammingczar wrote:It's sort of cheating to implement IO in a language that's already impure.

??? Why? What makes it "cheating"


Because if you translate what you did to Haskell, what you really have there is Identity. Specifically, only in a language where side effects exist outside IO can you pass nonIdempotentFunction to the constructor to begin with. That was more of a cheeky comment than a criticism of your code though. :P

Yes, if your language can't natively express non-idempotency, it's *almost* Identity. (Identity's value-extractor requires you to pass in the value you want to extract, while IO's value-extractor just requires you to call the function. Haskell, with its lack of nullary functions, can't actually express the latter natively, but that's a quirk of Haskell's model, not an intrinsic fact of the IO functor.)
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Mon Jun 13, 2016 8:41 pm UTC

EvanED wrote:Pretty sure I've posted this before, but my absolute favorite DailyWTF is this "false detector":

Code: Select all

public boolean checkFalse(Boolean bool)
{
  if (bool.booleanValue() == Boolean.FALSE.booleanValue())
  {
    return Boolean.FALSE.booleanValue();
  }
  else
  {
    return Boolean.TRUE.booleanValue();
  }
}


This is is like an onion of WTFs.


That's not right... that's not even wrong.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
Flumble
Yes Man
Posts: 2266
Joined: Sun Aug 05, 2012 9:35 pm UTC

Re: Coding: Fleeting Thoughts

Postby Flumble » Mon Jun 13, 2016 9:16 pm UTC

You, sir, name? wrote:
EvanED wrote:Pretty sure I've posted this before, but my absolute favorite DailyWTF is this "false detector":

Code: Select all

public boolean checkFalse(Boolean bool)
{
  if (bool.booleanValue() == Boolean.FALSE.booleanValue())
  {
    return Boolean.FALSE.booleanValue();
  }
  else
  {
    return Boolean.TRUE.booleanValue();
  }
}


This is is like an onion of WTFs.


That's not right... that's not even wrong.

But it is. It doesn't check for null!


Return to “Coding”

Who is online

Users browsing this forum: No registered users and 7 guests