Live data from Hacker News

BLisp: A Statically Typed Lisp Like Language

ytakano.github.io

31–40 of 51 posts

Re: BLisp: A Statically Typed Lisp Like Language

#31
post #25
post #7

Why require Pure to be an annotation - why not make that the default without annotation - no effects? (Same as in Haskell)

All functions in Haskell are pure: the function `putStrLn :: String -> IO ()` returns the same IO action for the given input.

But you don't need to annotate that, i.e `putStrLn :: Pure (String -> IO ())` (or as in the OP lisp: `Pure (-> String (IO ()))`)

Re: BLisp: A Statically Typed Lisp Like Language

#32
post #7

Why require Pure to be an annotation - why not make that the default without annotation - no effects? (Same as in Haskell)

Because it’s an effect system, it’s not returning monads. It’s a different kind of type system with different restrictions and benefits. You could make every function implicitly pure, but that would be syntactic sugar, as opposed to Haskell where pure-as-default is a consequence of how the type system is structured.

Re: BLisp: A Statically Typed Lisp Like Language

#33
post #24

I wasn't fully able to tell if this was interpreted or compiled? In any case, it looks neat, I think the intersection of static types and Lisps is a space that needs more experimentation with, so I'm happy to see that. I hope eventually it gains more effects as well, with only Pure and IO, you can't do much of the cool things that effect systems bring.

It seems to be embedded in Rust: https://github.com/ytakano/blisp#how-to-use

so I would guess interpreted

Re: BLisp: A Statically Typed Lisp Like Language

#34
post #19

Earlier quoted context omitted.

Not OP so there might be others, but the two that I see are: * most crucially, x isn't actually spliced in, meaning that the macro always literally expands to (+ x x). For example, (+ (double 2) 5) just expands to (+ (+ x x) 5), which will either crash if x is undefined or do something unexpected if x is. * Even if x were spliced in properly, it gets evaluated twice. That's wasteful at best, and if x has some kind of…

Just for completeness, the correct macro would look like this: (defmacro double (x) (let ((temp (gensym)) `(let ((,temp ,x)) (+ temp temp)))) This way, when you write (double (parse-integer (read-line)) it would expand to (let ((#:uniqueName123 (parse-integer (read-line))) (+ #:uniqueName123 #:unique_symbol_123)) This guarantees that that the macro will not accidentally refer to some outside variable, and that it's a…

I made a mistake when copy pasting and renaming something, the expanded code should have been

  (let ((#:uniqueName123 (parse-integer (read-line)))
    (+ #:uniqueName123 #:uniqueName123))

Re: BLisp: A Statically Typed Lisp Like Language

#35
post #19

Earlier quoted context omitted.

Not OP so there might be others, but the two that I see are: * most crucially, x isn't actually spliced in, meaning that the macro always literally expands to (+ x x). For example, (+ (double 2) 5) just expands to (+ (+ x x) 5), which will either crash if x is undefined or do something unexpected if x is. * Even if x were spliced in properly, it gets evaluated twice. That's wasteful at best, and if x has some kind of…

Just for completeness, the correct macro would look like this: (defmacro double (x) (let ((temp (gensym)) `(let ((,temp ,x)) (+ temp temp)))) This way, when you write (double (parse-integer (read-line)) it would expand to (let ((#:uniqueName123 (parse-integer (read-line))) (+ #:uniqueName123 #:unique_symbol_123)) This guarantees that that the macro will not accidentally refer to some outside variable, and that it's a…

Surely

    (defmacro double (x)
        (let ((temp (gensym))
        `(let ((,temp ,x))
           (+ ,temp ,temp))))

Re: BLisp: A Statically Typed Lisp Like Language

#36
post #35

Earlier quoted context omitted.

Just for completeness, the correct macro would look like this: (defmacro double (x) (let ((temp (gensym)) `(let ((,temp ,x)) (+ temp temp)))) This way, when you write (double (parse-integer (read-line)) it would expand to (let ((#:uniqueName123 (parse-integer (read-line))) (+ #:uniqueName123 #:unique_symbol_123)) This guarantees that that the macro will not accidentally refer to some outside variable, and that it's a…

Surely (defmacro double (x) (let ((temp (gensym)) `(let ((,temp ,x)) (+ ,temp ,temp))))

Oops, yes...

Re: BLisp: A Statically Typed Lisp Like Language

#37
post #12

Earlier quoted context omitted.

For the same reason that it wouldn't be a normal function in any Lisp. The difference is that the macro expander keeps a list of macros (separate from the set of normal functions in the program), so that when it sees a list with a symbol in the first position, it can look up that symbol in its macro list, and if it is a macro, it can call the macro and replace the macro call form with the return value of the macro. T…

I see, thank you so much for the explanation. I think to clarify what I said - I didn't mean that static typing and macros are excluding each other. But I think you can either have a sound static type system and highly restricted macros, or less restricted macros but only an unsound type system. That's what I meant with "conflict".

No problem.

I'm interested to hear though why you think unrestricted macros make the type system unsound. Can you explain? The code generated by macros would be type-checked in the scheme I described, and type-unsafe code can't be executed by the macro itself, so it seems safe to me.

Re: BLisp: A Statically Typed Lisp Like Language

#38
post #6

Earlier quoted context omitted.

> I always feel that for lisp-like languages it's just not a good idea to make them statically typed. Their power is derived from macros and the fact that code is data and the other way around. I completely agree with the idea that their power is derived from macros, but I vehemently disagree that macros are incompatible with a static type system. The type of a form can be just a simple ADT data Form = FInt Int | FCo…

> (defmacro double (x) > `(* x x)) Two bugs in two lines. Lisp is indeed a powerful language.

This wasn't meant to be valid code in any existing lisp, just lisp pseudo code. The behaviors you describe as bugs don't exist in all macro systems; for example, some macro systems automatically splice symbols from the context, some automatically prevent double-evaluation, and in purely functional languages double-evaluation doesn't matter anyway. I didn't want to get distracted by these irrelevant details from my main point, which, alas, has happened anyway.

Re: BLisp: A Statically Typed Lisp Like Language

#39
post #37

Earlier quoted context omitted.

I see, thank you so much for the explanation. I think to clarify what I said - I didn't mean that static typing and macros are excluding each other. But I think you can either have a sound static type system and highly restricted macros, or less restricted macros but only an unsound type system. That's what I meant with "conflict".

No problem. I'm interested to hear though why you think unrestricted macros make the type system unsound. Can you explain? The code generated by macros would be type-checked in the scheme I described, and type-unsafe code can't be executed by the macro itself, so it seems safe to me.

That is more of my impression that I have gathered from watching programming languages evolving. Rust is a good example, where they tried hard and the macros still become unsound. Scala is another good example where macros where unsound first and they had a really hard time to make them sound and work with the type-system - they lost a lot of power in the process.

Now, that doesn't have to mean that there is some inherential that stops the combination from super powerful macros and sound statical types from working together, but if anything, there is at least a compromise to be made in terms of resources, because it seems you would have to put a lot of effort into it.

> The code generated by macros would be type-checked in the scheme I described, and type-unsafe code can't be executed by the macro itself

Well, I would already consider this to be quite a big restriction though.

Re: BLisp: A Statically Typed Lisp Like Language

#40

Earlier quoted context omitted.

How do you feel about typed Racket?

I have never used racket, but what I have seen so far is pretty cool. But for typed Racket, I don't have a good feeling about it either. In particular because it is gradually typed, which kind of defeats the purpose, even though it might be practically useful. But I prefer to have actually compiler guarantees and not just best-effort help.

This might be a confusion about what "gradual typing" means. Typed Racket is a sound type system, and not just best effort. You get real compiler guarantees.
Post reply on HN