Shen-Language / wiki

71 stars 1 forks source link

intern(true) return a boolean? #2

Closed tiancaiamao closed 6 years ago

tiancaiamao commented 6 years ago

I'm porting Shen to Go https://github.com/tiancaiamao/shen-go, and I meet many strange behavior of klambda during that time.

One of which is, the return value of intern(true), need to be a boolean type. It's completely beyond my comprehension!! and cost half a day to debug this problem. I think it should be explained in the wiki, so other implementer would not trap by it again.

tiancaiamao commented 6 years ago

And that when read-byte meet EOF, it returns -1 rather than a error, I think this should also be documented.

rkoeninger commented 6 years ago

@tiancaiamao Yes, booleans can be a bit confusing - they are just the symbols true and false, but the symbol? function will also return false for them.

Refer to the definition of symbol? where it explicitly excludes booleans and the definition of boolean? where it just checks if the argument one of two symbols.

These should all evaluate to false:

(symbol? true) -> false (symbol? false) -> false (symbol? (intern "true")) -> false (symbol? (intern "false")) -> false

These should all evaluate to true:

(boolean? true) -> true (boolean? false) -> true (boolean? (intern "true")) -> true (boolean? (intern "false")) -> true

I would recommend not modelling a boolean type in your port at all.

In my F# port, you can see there is no primitive boolean. Instead, it's just Sym "true" and Sym "false" and it's an error for a conditional to evaluate to anything else.


Also, the fact that read-byte is supposed to return -1 is mentioned in the KLambda page in the wiki, but may not be mentioned on the shen website or in the doc/ folder in Shen-Language/shen-sources.

Documentation is still a little fragmented, so the official website docs might have information that the wiki doesn't and vice versa.


Also, double-check that symbol? won't return true for functions, streams, errors, etc, as it considers a value a symbol if it is not a string, number or boolean and it's str value is a valid symbol.

tiancaiamao commented 6 years ago

@rkoeninger

Thank you for clarify it!

In my F# port, you can see there is no primitive boolean. Instead, it's just Sym "true" and Sym "false" and it's an error for a conditional to evaluate to anything else.

Yes, that's a tricky way to work around the problem. I've update the wiki about intern primitive.