laurent.orseau
2020-12-14 09:12:02

… so that, in particular, starting racket with just racket/base would be faster.


laurent.orseau
2020-12-14 09:13:08

That said, we could well have a racket/core or racket/base-small or whatever that is even smaller, while keeping racket/base .


kellysmith12.21
2020-12-14 23:50:39

(meta question) I’m making a #lang and would like to discuss it and get feedback and ideas for improvements/additions. I think that just saying, “look at this big project and tell me what you think” is probably not a great way to start a useful discussion, but I’m new to language design and don’t have an intuition for this. What things could I focus on to facilitate the discussion?


notjack
2020-12-15 02:32:25

I think giving specific use cases before explaining anything else helps a lot when discussing languages (and also libraries and frameworks)


notjack
2020-12-15 02:33:42

Language design is a huge space and exploring it with people is way easier if those people have a roughly shared understanding of their goals


notjack
2020-12-15 02:34:48

and I like using use cases as goals because otherwise people tend to pick abstract goals that are easy for other people to misunderstand and which are missing a lot of context


kellysmith12.21
2020-12-15 03:09:31

The lang I’m making is, essentially, a combination of smaller, separate ideas that I’ve been considering for a while: • A core language smaller than racket/base. • “Tidy” and “modern” APIs. • Bind with patterns, instead of variables. • Emphasize pattern matching. • Surface syntax that uses fewer parens, but is still based on s-exprs. • (gently) enforce separation of “pure” and “impure” code. • Emphasize immutable data and higher-order/functional programming. • Use generic operations throughout the stdlib. • Be expressive enough to be useful on its own. • Be able to cooperate with existing Racket libraries, if needed/desired.


kellysmith12.21
2020-12-15 03:12:26

Many of my goals have been explored/implemented separately in Racket libraries and langs. Since I’m trying to achieve all those goals in one lang, some of my work is putting together or wrapping existing things and some of my work is building something that fits well with the other parts.


kellysmith12.21
2020-12-15 03:14:42

Since those goals are really broad and vague, I can elaborate on them, individually, and provide examples of what I’d like things to look like.


wanpeebaw
2020-12-15 03:16:37

Is there any reason why these layers cannot be added?


notjack
2020-12-15 03:42:57

Migration work is the main obstacle. If racket created a new racket/XXX module every year it’d drive people up a wall.


notjack
2020-12-15 03:43:22

I like all those things


notjack
2020-12-15 03:44:17

a weird thing I’ve encountered with “bind with patterns, instead of variables”: you can’t use define to mean both “bind variables” and “create a function” anymore


kellysmith12.21
2020-12-15 03:48:02

Because of the syntactic changes I’ve included, my define form is still able to do double duty.


samth
2020-12-15 03:54:10

Also, racket/base is pretty small, and things you could cut would either not help much (like filter, say) or be a big step down in functionality (like for).


samth
2020-12-15 03:54:55

I’m less sure a smaller racket/base would be that helpful — a smaller “base” package would be very nice, but that would just be a lot of re-implementation work.


notjack
2020-12-15 04:00:05

Oh neat, what did you change?


kellysmith12.21
2020-12-15 04:01:05

As an example, this is the factorial function, in my language: {define fact : {-> natural? natural?} (fact n) ⇒ (fact-acc n 1) #:where (fact-acc n acc) ⇒ {if (= 0 n) acc (fact-acc (sub1 n) (* n acc))}}


notjack
2020-12-15 04:10:54

ah so it’s using the haskell-y where thing for locals defined after their use sites?


kellysmith12.21
2020-12-15 04:13:27

Yes, the #:where clause is translated into a define in the underlying Racket procedure body, before the result expression.


notjack
2020-12-15 04:14:50

What do the curly braces mean?


kellysmith12.21
2020-12-15 04:19:46

Unlike Racket, different delimiters have different meanings. (Unless overridden by a macro) parens are for procedure application and braces are for syntactic forms.


notjack
2020-12-15 04:24:35

are parens also for pattern matching?


notjack
2020-12-15 04:26:44

to me, the main benefits of making racket/base smaller is avoiding identifier conflicts


notjack
2020-12-15 04:27:46

it’s very difficult for libraries to provide things with the same name as any of the exports of racket/base without breaking stuff


notjack
2020-12-15 04:28:14

usually scribble docs, in my experience, since they’ll do (require (for-label racket/base some-library))


kellysmith12.21
2020-12-15 04:29:58

The define form expects a function header in parens, so that it looks like a function call. Since match-expanders (patterns) are syntax, they are written with braces in expressions. For symmetry, forms that use matching also expect patterns to be written with braces.

example: {define (flip {list a b}) ⇒ {list b a}}


notjack
2020-12-15 04:35:00

Is that {list b a} expression on the right a function application?


kellysmith12.21
2020-12-15 04:46:22

No, that’s a pattern for list-building. One radical thing I’ve done is eliminate (quasi)quotation for list matching and building. Instead, I provide a match expander that uses a new syntax for lists.


kellysmith12.21
2020-12-15 04:47:34

(Part of the modernization is removing lists from their position as the central datatype.)


kellysmith12.21
2020-12-15 07:03:02

Although my language is currently implemented as Racket macros, I plan on switching to using <https://docs.racket-lang.org/ee-lib/index.html#%28part._top%29|the “ee-lib”> and building a self-contained core language that is compiled into Racket.