Live data from Hacker News

A Haskell Programmer Tries to Learn Racket

artyom.me

121–130 of 163 posts

Re: A Haskell Programmer Tries to Learn Racket

#121

Earlier quoted context omitted.

It's ironic that Haskell is such a language: it grows from a tight, small core into larger and greater abilities as you learn it even without using its extensions. I agree that Common Lisp a very powerful language, but I can't live with all that power uncontrollably thrown on me. Common Lisp grossly lacks self-discipline and self-limitation when it's needed.

I suspect the parent thread was dreaming of a framework where languages with arbitrary syntax can be mixed and matched in user-defined ways. Haskell isn't necessarily that language, partly because it still requires centralized coordination of development of these "extensions" to ensure they're interoperable - that is, there is only one parser for the language and its supported extensions, and many of them are build i…

I don't think the problem stops at syntax. It's possibly an even bigger issue that mixing different language semantics can be awkward. As a big obvious example, a language where all objects are nullable will interface awkwardly with one that only has option types. Similarly, interfacing with something like Smalltalk (which uses methods for flow control) or Forth (which…is Forth) would be awkward from a language that's more like C++.

Even in an environment like the JVM which specifies a lot of stuff for you, it's awkward to call into Clojure from Java because of the semantic differences.

Re: A Haskell Programmer Tries to Learn Racket

#122

Earlier quoted context omitted.

My question is, given the cons pair is not a meaningful primitive datatype to modern CPUs (can't fit in a register unless you're using 32 bit atoms on a 64 bit CPU, the individual cells cannot be meaningfully manipulated while packed into a single register even in that case...), is there a good reason to use an unrestricted pair/2-tuple/2 element vector for the sexp representation? Would it be "wrong" to remove dotte…

Going a little Abelson&Sussman, the utility of cons persists because it is a powerful abstraction. Fitting into registers was, as a scholastic might say, an as accidental feature as the input line voltage of a toaster [110 @ 60Hz makes things easier in this part of the world but isn't intrinsic to making crisp English muffins]. cons is useful for dealing with linked memory structures, including singlely linked lists…

I think the question is more along the lines of "Should the core data type be the cons cell rather than the list?" Clojure takes the approach the GP was talking about. It has lists with heads and tails, but it does not have dotted pairs. The tail of a list is always a list.

Re: A Haskell Programmer Tries to Learn Racket

#123
post #3

"...but nothing beyond that. As long as Node.js exists in this world, I can't truly hate anything else." I found this hilarious. I am also rather underwhelmed (to be nice) with Nodejs and a little bothered at its wide adoption. I have also been learning racket recently; my formal language and functional programming class uses it. I had some previous experience with common lisp but the raw nature of scheme still pleas…

[deleted]

Re: A Haskell Programmer Tries to Learn Racket

#126
post #82

Earlier quoted context omitted.

Named arguments are there to be interfaces to procedures. With hash-tables you know nothing about them. With named arguments, we can ask for argument lists, check for missing arguments, complete arguments, prompt for arguments, ... Much of that can be done in the IDE or at compile time. Named arguments had been introduced to Lisp with MDL (a Lisp dialect, brought to Lisp Machine Lisp and then to Common Lisp). Using h…

; CL keyword arg syntax, taken from Practical Common Lisp (defun foo (&key (a 0) (b 0)) (+ a b)) (foo :a 1) -> 1 (foo :a 1 :b 2) -> 3 ; hypothetical table keyword arg syntax ; clojure defines commas to be whitespace, you can pretend they aren't there if you want (defun foo ({a: 0, b: 0}) (+ a b)) (foo {a: 1}) -> 1 (foo {a: 1, b: 2}) -> 3 I fail to see why the table syntax would be any less usable or introspectable by…

Basically the syntax for specifying keyword arglists is based on assoc lists. The calling syntax is based on property lists.

There is nothing to be gained by hashtables.

The Common Lisp keyword syntax actually is a bit more powerful then what your PCL example shows:

(defun foo (&key ((var keyword) init var-arg-supplied-p) ...)

Generally I think it is a slight mistake to use specific data types in arglists - basically mixing syntax and data types.

Re: A Haskell Programmer Tries to Learn Racket

#127
post #100

Earlier quoted context omitted.

I dream of a modular language in which languages, or dialects , can be built from a small base language, which can then be extended, and so on. Of the languages that I've seen, Racket looks the most promising. Forth might be good for this, too, but to build large hierarchies of languages seems the antithesis of Forth - or at least, Chuck Moore's - philosophy. On the other hand, such a language might just end up as an…

It's ironic that Haskell is such a language: it grows from a tight, small core into larger and greater abilities as you learn it even without using its extensions. I agree that Common Lisp a very powerful language, but I can't live with all that power uncontrollably thrown on me. Common Lisp grossly lacks self-discipline and self-limitation when it's needed.

Ugh, please let Common Lisp be. There's enough bondage & discipline languages already so it is nice to have CL on the opposite side of the spectrum.

Re: A Haskell Programmer Tries to Learn Racket

#128
post #49

Earlier quoted context omitted.

It has pedagogical value to define things in terms of a very small kernel language. You will find things like alists in fairly advanced books on lisp (e.g. Lisp In Small Pieces) simply because it reduces the number of extra concepts you need to explain. It's assumed that the reader can figure out how to make the code cleaner and more idiomatic as long as they understand the ideas being presented. Also I have made use…

>Also I have made use of improper lists in my code, usually when I need to do something with multiple values and I don't want to mess with multiple return values, or if I just want to create a list of tuples for some reason and don't feel like defining an actual struct (can't think of a good example right now...) I get what you're saying, but isn't this just a shortcoming of the language? It's pretty common to want t…

> It's pretty common to want to write something like [. . .] without wanting to destructure a list or use the call-values hack.

This makes no sense. You want feature X (the ability to return multiple values) without having to either (a) pick apart a simple structure containing those values or (b) assign names to those values, letting the runtime system pick them apart (or never stick them together, its choice) for you. So what more do you want?!

You want an option type, right? Well what's an option type? Let's consider Haskell:

data Maybe a = Nothing | Just a

No matter what kind of cleverness you do in memory or whatever, in the end this type is a tuple of two values: (constructor, data). The only special thing going on is that the type system makes sure that (a) constructor == Maybe or constructor == Just, and (b) if constructor == Maybe the data field is meaningless (has no type, can't be read, does not effect equality, whatever).

But it's still a tuple. The cons cell is the exact same thing in the absence of a strict compile-time type system, except for your code example we have it flipped: (data, constructor) (well, actually you seem to have a flipped 'Either String a' going on there, but let's stick with option for now) where data is actual data or nil when meaningless, and constructor is like Just when nil and like Nothing when true (btw, lisp convention is the other way around; second value is true like Just and false/nil like Nothing).

Just like the original linked article, what your complaint boils down to is "non-compile-time-typed systems allow you to do things which would break compile-time-typed systems"—and while I love compile-time typing as much as the next Haskell aficionado, I don't demand compile-time typing in a language [family] whose very essence is its absence.

EDIT: if you could reply and explain what would resolve this "shortcoming of the language", maybe I could understand better what you're trying to say...

Re: A Haskell Programmer Tries to Learn Racket

#129

Earlier quoted context omitted.

I come from a background using Common Lisp for system and web development so I may see things differently than people who were introduced to it academically. Your code looks great, mine just needed to compile :) The cons pair is a a really powerful primitive data structure, it is the linked list of Lisp. You can build a lot of powerful structures given this great base. I really don't it matters what architecture your…

I mean, it's neat that you can build everything out of cons, in the sense that it's neat that Turing machines and the lambda calculus can perform any computation, but that doesn't mean it's a good idea to so in your code, any more than encoding numbers with Church numerals. Why use alists when you can use hash tables, why use... weird SICP-style struct list things when you could just use structs/vectors, etc. >Hash T…

I don't understand the argument for using a hash-table for kw-args. Hash tables only win against plists when you don't need to read every single element; when you always need to read every single element, then it's a losing proposition to use a hash-table instead of a plist.

Yes I agree with your later comment about syntactic blessing and all, but I think you picked a terrible example by choosing the single place in lisp where plists make more sense than hash tables.

Re: A Haskell Programmer Tries to Learn Racket

#130

Earlier quoted context omitted.

> I strongly doubt your compiler will transform all the literal alists in your program into hash tables, Time for experiment. SBCL doesn't, as far as I know. But you seem to imply that it is always better to use hash-tables, and I don't think so (even though hash-table can be implemented in a smart way, like in Lua). Under roughly 10 elements, alist result in shorter code. (defun my-fun (x) (declare (optimize (speed…

Microbenchmarks are fun but silly. I tried to write a similar one for Lua, but LuaJIT ultimately recognized the program was useless and boiled it down to a 3 instruction loop: loop: add ebp, 1 cmp ebp, 10000000 jle loop Anyway, in regards to your results, I could be wrong, but I think I read somewhere that LuaJIT uses linear search for tiny tables for this reason. Dunno what the threshold is, if there is one. The per…

> ... recognized the program was useless and boiled it down to a 3 instruction loop

The loop itself is quite useless, why wasn't it also removed ? (Just kidding)

I don't have anything agains Lua or hash tables in principle. And of course tables are used in practice in CL code, but they aren't the primary data-structure.

> __index can be another table to searched if the lookup on the child fails (which in turn can have its own parent and so on)

> the first time a function like "GL.CreateShader" is called, the lookup fails, and the __index metamethod mangles the index name a bit and in turn calls (on Windows) the C function wglGetProcAddress to look up its address, which it then stores in the original table. Using this library, you can write code that uses GL functions willy-nilly, and their addresses will automatically be looked up at runtime the first time they are used.

So, it is an association list implemented using tables, where links are given by the __index property, using a metatable.

So maybe it is convenient after all to have a very simple data-structure like cons in a language and let more complex data be implemented with it, instead of the opposite.

Post reply on HN