
@dstorrs Can you plz elaborate on how did Racket help your baby-business?

I’m with @turbopape — would be very interested to learn more.

(would love to get stickers of new racket logo) https://racket-lang.org/logo-and-text-1-2.png

I think @ben ordered some from stickermule (but without the word)

I’d love both kinds

> Can you plz elaborate on how did Racket help your baby-business?
It’s allowing us to write code more and more quickly as we climb the learning curve. It has an excellent set of modules that solve most problems, and it’s easy to fill the gaps where they exist. There are some bits I’m not fond of — a lot of the functions have poor end weight and I feel that the design prioritizes other things over convenience, although I’m too uncoffeed to come up with an example off the top of my head. Still, every language has warts and Racket’s are not nearly as bad as those of others.

We work on Mac but the fact that we can straightforwardly cross-compile to Windows is a big deal.

We haven’t gotten to that point yet, but it was one of our selection criteria.

Also, the docs. The Guide is really well done and makes it easy to get started. It needs some experience to find the Reference approachable, but once you have the experience it’s an excellent resource.

“poor end weight” - I’m not sure I understand what this means

It means that important elements come at the end instead of the beginning.

Sort is a perfect example: the sort function comes at the end, instead of at the beginning where I suggest it should be. Consider:
(sort (map first lst) string<?)
vs (sort string<? (map first lst))

The second tells you immediately that you’re going to be looking at strings, whereas the first (the one that actually exists) makes you look all the way to the bottom to find it.

Also, if your list generator is longer than a line or so then it makes it harder to identify the comparison function as attached to the sort.

Consider:
(sort (map (lambda (x) (string->symbol (string-append “key-” symbol->string x))) (hash-keys (some-func)) symbol<?)

Side comment: I recently stumbled over the fact that R6RS’s list-sort
and Racket’s sort
take the predicate and list in opposite orders. It was easy to recover from this stumble, of course, but it was "just another thing” that I had to change in order to port some Scheme code to Racket.

Hm, that’s a good point. It would be easy enough to write a macro that reversed the order.

I’ve already written a try/catch macro to stand in for ‘with-handlers’. That’s another example of poor end weight — the exception cases come at the front, distracting from the actual happy-path code that should be the focus.

You wouldn’t write a macro for that, you’d just write a function. Or import one of the existing functions under the other name. https://racket.slack.com/archives/general/p1484244074000172

just a side comment — the list argument coming first in sort
is consistent with (what I believe is) the general pattern of having data structures be the first argument to functions which operate on them. To me this is very normal and what I expect, YMMV I suppose.

Fair enough, although I would point out that ‘map’ does it the other way, as do ‘apply’ and ‘keyword-apply’

My point is less about whether it’s normal or standard and more about the actual user experience of it.

Just to be clear — I don’t mean to sound as though I’m coming into the channel and the first thing I’m doing is criticizing.

Yah I understand, just adding a thought

To quote @robby: > I think we’ve tried, with functions that came into our world post-Scheme, to have the argument order be that the first argument is the ADT that this function goes to and the subsequent arguments are not. So, if we were to add member today, we’d probably have it take the list first and the element second. In other words, since member is viewed as a “list-related” function, the list argument should come first.

Racket is really pleasant to work with, and has made me more productive.

@lexi.lambda / @robby : Is there a reason for that aside from culture?

Does it make the compiler code more efficient or such?

I don’t personally know, but the existence of optional arguments might contribute to that somewhat. In Haskell, the general convention is the opposite, but that’s because Haskell is different: all functions are curried and there are no optional arguments. In Racket, I think the distinction is more arbitrary.

Well, I would contend that the reason it’s being done this way is due to a desire to be consistent with a historical choice and that that choice was not optimal. It’s a bit of a put-up-or-shut-up thing, though — if I wanted to I could take the time to write a new #lang that reordered things to the way my clearly superior opinion and boundless experience say they should be.

(That was tongue-in-cheek.)

@dstorrs: @lexi.lambda I don’t really have a good rationale; my comment was more of an observation of history than anything. That said, you should DEFINITELY make your new awesome #lang.

Heh. Well, I’ll get right on that once my next shipment of tuits arrives.

@d_run good idea, I’ll order some and email the list

Optional arguments make it difficult to consistently put the ADT last. Optional args are rarely the ADT in question so they’d have to either be put first (requiring case-lambda), put last after the ADT breaking the pattern, or converted to keyword arguments which doesn’t always make sense

> put last after the ADT breaking the pattern,
Breaking the pattern of ‘ADT always comes last’, you mean?

Yup

Got it.

I come from a Perl background (braces himself for the backblast), which I think makes me a little less concerned about patterns like that than users of many other languages. At a conference I attended, Larry Wall once described Perl as “a blue-collar language”; among other things, it’s happy to discard consistency for usability.

In the example you gave I think the bigger usability issue was not having a way to make that lambda simpler :)

:stuck_out_tongue:

Probably a fair point, but whatever you feel about that example it’s representative of a general class of problems.

Sure, I can ‘define’ the lambda above the sort and then use it in the sort, but that’s a workaround. I would be doing that because the sort function has poor end weight, not because it’s the more sensible solution.

And yes, I could also do something like: (compose string->symbol (curry string-append “key-”) symbol->string) but that’s hardly better.

@dstorrs: Perl hacker here, also. waves
I find myself re-creating small parts of Perl in Racket when the design would benefit from it.

Solidarity, brother!

It’s interesting, as I learn Racket, to see all the things that Perl borrowed from LISP.

Anonymous subs being the first one that comes to mind.

Oh, absolutely. When I started Perl, I basically wrote C-style Perl (which you can get away with for quite a while). The mental shift in “thinking in Perl” made coming to Lisp far easier.

Yep. Also, both languages have a very long learning curve, which I like.

I particularly like that both languages give you the tools to shoot yourself in the foot and trust you not to.

I do miss Perl’s symbolic references and open namespaces, but I’ll trade them for Racket’s vast array of comprehensions and iterations, the macro system, and first class continuations.

^^ agreed. Perl composes very well (not in the same league as Rkt, but still good, considering). It’s fast, too. I miss regexps and how easy string mangling jobs are, but racket++
because I’m free to just build in that functionality, which is fab.

(I guess that should be (add1 racket)
instead :wink:)

laugh

Perhaps, yes.

Although I haven’t looked at namespaces enough to know if there’s a way to do Perl’s “install a new function in the namespace at runtime and have it be visible to the whole program, without using eval” trick. Is there?

@dstorrs no, and that’s definitely intentional (unless you’re at the repl)

@pkoronkevich has joined the channel

@dstorrs Shameless self plug: the compose-app
package I made would let you write (compose string->symbol (curry string-append "key-") symbol->string)
as (string->symbol .. string-append "key-" _ .. symbol->string)