Live data from Hacker News

Why Racket? Why Lisp?

practicaltypography.com

281–290 of 295 posts

Re: Why Racket? Why Lisp?

#281
post #278

Earlier quoted context omitted.

hmm... c = sqrt(a*a + b*b) (setf c (sqrt (+ (* a a) (* b b))))

Amusing... but to be fair, this is also an operator precedence issue where C is letting you drop several pairs.

>where C

...I think operator precedence allows the removal of the parenthesis for at least: Ada, C, C++, D, Dylan, Erlang, Fortran, Go, Haskell, Icon, Java, Javascript, Julia, Lua, Mathematica, OCaml, Pascal, Perl, Prolog, Python, QBasic, R, Ruby, Scala, and TCL.

Re: Why Racket? Why Lisp?

#282
Nice write-up. I really like Racket, but never had a chance to use it in a professional project so far.

By the way, Scribble (item 7) is an implementation of Literate Programming - a feature is some other languages too. In Haskell, for example, you can write programs in Latex with embedded code.

Re: Why Racket? Why Lisp?

#283

Some practical features I enjoy in CL: 1. Conditions and restarts : As far as error handling in programs go this is the most rock-solid system I've encountered. You can tell the system which bits of code, called restarts, are able to handle a given error condition in your code. The nice thing about that is you can choose the appropriate restart based on what you know at a higher-level in the program and continue that…

"CLOS allows me to dispatch based on the types of all of the arguments." But can it dispatch based on the return value?

Dispatch what where based on the return value of what?

Can you explain this with an example of what the syntax would look like, along with a description of the fantasy semantics?

Of course if a specializable argument to a CLOS generic function call is itself a function call expression, then it is evaluated to its return value, and the type of that value is dispatched on.

The return value of the generic function itself doesn't dispatch anywhere; return "dispatches" to the caller.

We can think about dispatching a different method based on some type which the caller expects. A way to do it in CLOS is to add an extra parameter, perhaps a class symbol. CLOS can dispatch on symbols via the (eql ...) specialization, so we can do something like (foo 'integer arg) to call that specialization of foo which returns integers. This won't be deduced from context; evaluation of a form is context free in ordinary Lisp. Doing that sort of thing requires a code walker to transform the program.

Re: Why Racket? Why Lisp?

#284

Earlier quoted context omitted.

"CLOS allows me to dispatch based on the types of all of the arguments." But can it dispatch based on the return value?

Dispatch what where based on the return value of what? Can you explain this with an example of what the syntax would look like, along with a description of the fantasy semantics? Of course if a specializable argument to a CLOS generic function call is itself a function call expression, then it is evaluated to its return value, and the type of that value is dispatched on. The return value of the generic function itsel…

Dispatch a function based on the value it is expected to return. The version of this that exists in some real programming languages at the moment (no "fantasy semantics") is dispatching based on the inferred type of the expression. Depending on your POV, that's quite arguably a part of the value returned. It obviously can't be chosen dynamically by the call, or we would be dealing with "fantasy semantics" (or a time machine).

Re: Why Racket? Why Lisp?

#285

Earlier quoted context omitted.

> The language called Haskell cannot produce side-effects. You see the side-effects when you execute a program. This is a rather meaningless distinction -- indeed, you can say the same thing about any other language on the planet. Programs written in C, Python, Ruby, ML, R, and Brainfuck only have side effects when you execute them. Obviously a C program just sitting on your hard drive unexecuted doesn't have any sid…

No. It's a very meaningful distinction, actually. Compare: Ruby: will_print = puts "hello world" # it already print to the screen! and will_print does not have any meaningful value -- indeed it's nil Haskell (demonstrated on the repl, which runs inside the IO monad): let willPrint = putStrLn "hello world" -- nothing gets printed! willPrint -- now the string gets printed ( only because the repl is inside the IO monad…

I know how IO works in Haskell, I don't need you to explain it to me. I still maintain the distinction you're making is meaningless -- Haskell code very clearly has side effects (mutating state, downloading files, sending data over a network, displaying pictures), and like any other programming language in existence, nothing actually happens until runtime.

Re: Why Racket? Why Lisp?

#286

Earlier quoted context omitted.

Dispatch what where based on the return value of what? Can you explain this with an example of what the syntax would look like, along with a description of the fantasy semantics? Of course if a specializable argument to a CLOS generic function call is itself a function call expression, then it is evaluated to its return value, and the type of that value is dispatched on. The return value of the generic function itsel…

Dispatch a function based on the value it is expected to return. The version of this that exists in some real programming languages at the moment (no "fantasy semantics") is dispatching based on the inferred type of the expression. Depending on your POV, that's quite arguably a part of the value returned. It obviously can't be chosen dynamically by the call, or we would be dealing with "fantasy semantics" (or a time…

"fantasy semantics" simply refers to the imagined semantics we want to have: the functional requirement. The semantics which isn't real right now, but we would like to implement.

(Not sure why I got a downvote. Is there a possible perception that I wasn't being civil?)

It occurs to me that some dynamic dispatch can take place based on what the method call returns. Suppose we split the computation of the function into two functions: the function proper, and a fixup which is applied to the return value.

The main function's method could have a CLOS :around method wrapped around it which obtains the return value of the primary method (via en explicit (call-next-method) call, and then invokes the fixup method on the argument. The fixup method is then dynamically dispatched on this return value, and possibly provides the ultimate return value.

Of course, this is different from dispatching a method based on the context in which it occurs. Still, no time machine needed.

Re: Why Racket? Why Lisp?

#287

Earlier quoted context omitted.

Dispatch a function based on the value it is expected to return. The version of this that exists in some real programming languages at the moment (no "fantasy semantics") is dispatching based on the inferred type of the expression. Depending on your POV, that's quite arguably a part of the value returned. It obviously can't be chosen dynamically by the call, or we would be dealing with "fantasy semantics" (or a time…

"fantasy semantics" simply refers to the imagined semantics we want to have: the functional requirement. The semantics which isn't real right now, but we would like to implement. (Not sure why I got a downvote. Is there a possible perception that I wasn't being civil?) It occurs to me that some dynamic dispatch can take place based on what the method call returns. Suppose we split the computation of the function into…

I did think "fantasy semantics" was meant to imply it was unlikely I could come up with coherent semantics for it. I wouldn't have considered that sufficient incivility to earn a down-vote, though.

Splitting functions is an interesting idea, though unless you're passing in context as an argument it'd be another way of dispatching on the same arguments (with, presumably, more user control but probably also more boiler plate).

Re: Why Racket? Why Lisp?

#288

Earlier quoted context omitted.

"fantasy semantics" simply refers to the imagined semantics we want to have: the functional requirement. The semantics which isn't real right now, but we would like to implement. (Not sure why I got a downvote. Is there a possible perception that I wasn't being civil?) It occurs to me that some dynamic dispatch can take place based on what the method call returns. Suppose we split the computation of the function into…

I did think "fantasy semantics" was meant to imply it was unlikely I could come up with coherent semantics for it. I wouldn't have considered that sufficient incivility to earn a down-vote, though. Splitting functions is an interesting idea, though unless you're passing in context as an argument it'd be another way of dispatching on the same arguments (with, presumably, more user control but probably also more boiler…

Yes, in this conception of what it means to dispatch on the actual returned type, the caller doesn't know, in the same sense that it doesn't know what sequence of methods is dispatched based on the arguments, either! It calls a generic function, which does some magic internally and produces a return value (or various side effects or both).

By the way, it appears I can explain why I had used the word "fantasy": I have been recently involved in some discussions about Gödel's Incompleteness Theorem. That stirred up distant memories of reading Hofstadter, dredging up some of his vocabulary.

Re: Why Racket? Why Lisp?

#289
I think it's kind of sad that most of the comments in this thread are about other languages than Racket and only barely touch on the articles points (mostly the stuff you don't need to actually try the language (or any lisp) to comment on). I think it says a lot about what the crowd on HN is really all about.

Re: Why Racket? Why Lisp?

#290
post #278

Earlier quoted context omitted.

hmm... c = sqrt(a*a + b*b) (setf c (sqrt (+ (* a a) (* b b))))

Amusing... but to be fair, this is also an operator precedence issue where C is letting you drop several pairs.

I don't see how that is supposed to be a valid excuse. Non-lisps tend to support operator precedence, reducing the number of parens significantly. Thus, the argument "other languages require the same number of parens" is completely false.
Post reply on HN