Live data from Hacker News

A Haskell Programmer Tries to Learn Racket

artyom.me

41–50 of 163 posts

Re: A Haskell Programmer Tries to Learn Racket

#41
post #20
post #17

Earlier quoted context omitted.

My theories: 1. Using the same programming language on both sides of HTTP often appeals to a developers visceral sense of elegance, or tidiness, even though it this alone inherently solves no existing problems. 2. It's powered by Googles V8 engine, which means people already associate it with this "super fast JIT" thing that lives in their favourite browser. It must be efficient, right? 3. The crowned alternative is…

1. There is a concrete advantage of shared code.

There are multiple concrete advantages.

I've recently worked on a few web apps which use ClojureScript/Clojure on the the client/server. Prior to that I mostly worked on web apps that were CoffeeScript/Python.

The first difference I took note of was how easy and seamless it was to move EDN structures back and forth between the client and the server. Of course this is a pretty minor difference as it's not exactly hard to pass JSON back and forth from CoffeeScript (or Javascript) to Python.

But then I started using Prismatic's Schema library. Schema is essentially a lightweight (gradual/optional) type system. Schema is written in cljx which means it works with both Clojure and ClojureScript. This means I could write my schema definitions once (also in cljx) and use them on both sides of the pipe. Schemas end up being similar to class hierarchies in an OO language. (So, for example, in one project I had a User schema and a Project schema and Project's had an "owner" fieldthat was a User, etc).

This ended up being really nice because now I still get the full dynamicity of Clojure(Script) but everywhere that I'm dealing with these core "types" I can validate the schemas. So I validated them going in/out of database access functions, I validated them going in/out of the server, in/out of the client, in/out of various specific functions on both the client and the server, etc. Wherever it made sense.

Of course in my old CoffeeScript+Python days there was nothing stopping me or anyone else from writing something like Schema and implementing both CoffeeScript and Python versions but it would be a lot more work upfront and in perpetuity to maintain 2 versions. But be that as a it may, for whatever reason, this type of tool doesn't actually get created that often in more heterogenous environments. (And I would argue they on balance, not as powerful/effective/simple/etc when they are created in those environments).

But honestly, for me personally, I think the biggest benefit of using a single language is just the reduction in mental baggage and context switching you have to deal with. I never found CoffeeScript+Python (or Javascript+Ruby or Javascript+Java or whatever) particularly challenging or wearisome while I was working with them, but having now accumulated a significant number of hours on the ClojureScript+Clojure combo it's very noticeable when I go back and work on old heterogenous projects.

Of course the plural of anecdote is not data, and my experience is definitely biased by the fact that Clojure and ClojureScript are just such a pleasure to work with all around. In the end though, while I'm not personally a fan of Javascript or Node.js, I now fully understand why the people that like Javascript love Node.js for giving them the gift of single language development.

Re: A Haskell Programmer Tries to Learn Racket

#42

As others have said, this does justice to the idea of actually learning a new language...or perhaps because it is Racket a new family or ecosystem of languages. Anyway, if you're still curious about pairs verus lists and why anyone would use dotted pairs, I like to think about it as where Lisps show that they are from the age when running close to the metal was a given. And it all goes back to car and cdr and the fac…

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 dotted pair notation and make sexps a restricted type whose cdr could only be another pair or the empty list? You'd have to give up alists, but those would probably be better served by doing as Clojure does and introducing a hash table syntax.

Other than alists, simplifying the implementation[1], and tradition, I can't think of a good reason to keep improper lists and dotted pair notation around. They aren't really that useful, confuse newcomers, and encourage the use of inefficient data structures. I haven't written much Lisp, but when I see a dotted pair (usually in the context of an alist or some hideous approximation of a struct[2]), it comes across as a "code smell" to me, like "this person is taking SICP too literally."

[1] You pay for extra reader syntax, but gain uniformity in your treatment of the car and cdr cells. On the other hand, maybe you could optimize the cdr cell a bit if it only needed to address pairs and not arbitrary atoms.

[2]

  ;; barfage
  (define (make-thing a b c) (cons a (cons b c))) ; barf
  (define (thing-field-a x) (car x))
  (define (thing-field-b x) (cadr x))
  (define (thing-field-c x) (cddr x)) ; more barf

Re: A Haskell Programmer Tries to Learn Racket

#43
Web apps are a hack on a hack, yes. But it's kind of ironic he hates Javascript so much when Javascript is a pretty cool programming language heavily influenced by Scheme, which is awfully similar to Racket.

But hey, I like people who call it like they see it, and there certainly are some drawbacks to Javascript too.

Re: A Haskell Programmer Tries to Learn Racket

#44
post #38
post #28

Earlier quoted context omitted.

Yeah, but I've basically never seen anybody suggest that Racket is a great language for prod.

Naughty Dog has used Racket as a scripting language in several of their video games for the PS3.

Slightly misleading, they don't actually run Racket on the PS3. IIRC, they created a DSL for game logic in Racket and wrote a special compiler for that DSL.

That's still a good example of a "real" program written in Racket, but it doesn't prove that Racket is a good choice for programs that need all the resources they can get.

Re: A Haskell Programmer Tries to Learn Racket

#45

As others have said, this does justice to the idea of actually learning a new language...or perhaps because it is Racket a new family or ecosystem of languages. Anyway, if you're still curious about pairs verus lists and why anyone would use dotted pairs, I like to think about it as where Lisps show that they are from the age when running close to the metal was a given. And it all goes back to car and cdr and the fac…

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…

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 running on.

Do they really confuse people new to Lisp? car+cdr is a pretty simple concept, when talking to new Lispers they usually don't complain about this.

Hash Tables are part of the Common Lisp Hyperspec so that is a non issue, they have been first class citizens since before Clojure existed (and are nicely integrated into things like loop)

Re: A Haskell Programmer Tries to Learn Racket

#47

A friend of a friend has considerably code in Scheme, Common Lisp and Clojure, when you ask him which is the true Lisp, guess what will he answer? Haskell! Haskell does really create a big impact on some developers. Just an anecdote ;)

I think it can't be "the true Lisp" without cleaner macros. Of course, that doesn't stop Haskell from being a great Haskell.

Re: A Haskell Programmer Tries to Learn Racket

#48

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…

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 think the parent was saying car and cdr are confusing because they don't actually map to registers (i.e. address register and decrement register). On the other hand you don't have to think too hard about the composed versions of them (caddr, cadar, etc...) but they can easily make your code seem obfuscated. Racket offers both that and first/rest anyway so you can choose which style you prefer.

Re: A Haskell Programmer Tries to Learn Racket

#49

As others have said, this does justice to the idea of actually learning a new language...or perhaps because it is Racket a new family or ecosystem of languages. Anyway, if you're still curious about pairs verus lists and why anyone would use dotted pairs, I like to think about it as where Lisps show that they are from the age when running close to the metal was a given. And it all goes back to car and cdr and the fac…

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…

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 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...)

Re: A Haskell Programmer Tries to Learn Racket

#50
post #35

Earlier quoted context omitted.

Straight from the horse's mouth: "Node is popular because it allows normal people to do high concurrency servers. It's not the fastest or leanest or even very well put together - but it makes good trade offs in terms of cognitive overhead, simplicity of implementation, and performance. I have a lot of problems with Node myself - but the single event loop per process is not one of them. I think that is a good programm…

> The future of server programming does not have parallel access to shared memory. Yeah but it could be IO parallelism. There could be two instances of callback chains of sequence C1->C2->C3 started such that the the second starts before the first one finished. As in C1->C2 ran then C1 gets called again. If in those callbacks you update a data structure (a database record?), you now accessed that data in parallel. So…

There's some need to synchronize, but hot damn is it simpler when you're dealing with sensible blocks of high-level statements than when you're dealing with out-of-order parts of assembly instructions.
Post reply on HN