Closed crusaderky closed 5 years ago
I think Rockstar basically has to have weak typing. Because there is no easy way of doing method calls, and those would just make the lyrics harder to read, we really want to encourage implicit conversions like this. It is conventional to use If a cat is nothing
which is already an implicit conversion from null to number (or vise versa).
Officially defining the semantics would be useful.
Weak typing would make parsers in strong typed language way harder. There's not even syntax over string concatenation, I think we should go easy
How do you figure that? I wrote my parser in scala, a very strongly typed language, and had no problem getting the semantics we wanted. Yes it's a functional programming language, but I feel like I would have no problem if I had written it in c++ (besides much longer development time :P)
Also we want something like "left" plus "right"
to work, and that would only be available in a weekly typed language (or strongly typed with tons of implicit conversions)
You're right, it would be a very good idea. So far I've basically assumed the type system works like JavaScript - which has some some well-documented idiosyncracies (WAT?) but is widely-understand and works pretty well most of the time in most cases. I certainly wouldn't envisage ever doing type checking at compile time.
and to @cwfitzgerald's point - it's fairly easy writing a parser for a weak-typed language using a strong-typed language, but if Rockstar was strongly typed implementing a Rockstar parser/transpiler that ran in JavaScript (for the inevitable interactive web Rockstar thing) might become significantly harder. So I think that's another strong point in favour of the language being weakly typed.
"left" + "right"
is "leftright"
, and it doesn't do silent type conversions. Strongly typed languages have this syntax (eg Python). The thing is:
My body is perfect
Dylan says 7
If Dylan is the same as my body
If Rockstar was a weakly typed language, this if should evaluate to True. However, in Python it'd check if "7" is equal to 7, which is not. I'd have to do some crazy shit to make this happen. Maybe convert everything to a string in a comparison. Even this way, I'd still have trouble comparing "1.0" with "1"
@yanorestes You're totally right, that's what happens when you post things first thing in the morning :smile:.
As for the semantics of that snippet, I would argue that it should evaluate to true. Now, the direction of the conversion is important. I think it should go in the "sane" direction string -> number, and if that fails, don't throw an exception, simply return false.
That's plausible. Then I could just have a function that compare two variables, with a try/except inside
Should I make these changes on rockstar-py? @dylanbeattie is weak typing official?
I think we should define a list of the acceptable conversions before making it official, if you give me a bit I can write up what I think should be an official list.
Great! I'll wait;)
This list assumes functions are just objects within rockstar's object model. Additionally, the order of arguments is irrelevant. List should be complete, but if I forgot anything, let me know and I'll amend to it.
Less than, Less, Greater, and Greater than are only defined if the operands are Numbers or are implicitly converted as such.
0
is un-truthyConversions other than the listed are errors.
true
or false
null
mysterious
@cwfitzgerald Looks great! A few questions:
@wolfgang42 To answer your questions:
@cwfitzgerald For #1, I am wondering what you mean by "Less than, Less, Greater, and Greater than are only defined if the operands are Numbers or are implicitly converted as such," especially since you have just defined them for Strings.
This attempts to be a more complete overview of Rockstar's type behavior, with better wording and taking into account string operations, and truthiness.
Rockstar uses a very similar type system to that defined by the ECMAScript type system, except undefined
doesn't sound very rock'n'roll so we use mysterious
instead.
mysterious
nothing
, nowhere
, nobody
, empty
and gone
are defined as aliases for null
true
and false
. (The keywords maybe
and definitely maybe
are reserved for future use)
right
, yes
and ok
are valid aliases for true
wrong
, no
and lies
are valid aliases for false
Functions are just objects with a function call operator.
The following examples all use c style syntax for explaining what things do.
The higher, the tighter the binding. This is the precedence we generally expect from our math.
A taking B times C plus D times E and F
is equivalent to ((A(B) * C) + (D * E)) && F
A taking B taking C, D
is equivalent to A(B(C, D)
NOT A(B(C), D)
.The results of comparisons often rely on a concept called 'Truthiness'. If the value is truthy, it will be implicitly converted to true. If it is falsy, it will be implicitly converted to false.
Equality comparisons (is
, ain't
, is not
) are allowed between any two operands of the same type. Objects are checked by reference equality, all other types are checked by value equality.
Ordering comparisons (is higher than
, is lower than
, is as high as
, and is as low as
) are only allowed if the operands are both Numbers or both Strings or they are converted to such an arrangement according to the rules below. Numbers are compared as expected, Strings are compared lexicographically.
"1" is 1
evaluates to true because "1"
gets converted to the number 1
"2" ain't Mysterious
evaluates to true because all types are non equal to mysterious, besides mysterious itself. "02" < "10"
is true because of the lexicographical comparison between 0
and 1
shows that the first string is less than the second string.True < 10
is an error because 10
gets coerced into True
due to the comparison with a boolean and there is no allowed ordering comparisons between booleans.Conversions other than the listed are errors.
00.1000
gets serialized to 0.1
true
or false
null
mysterious
@cwfitzgerald +1, though I still wonder why String is greater than Boolean
is undefined rather than an error.
@Wolfgang undefined means it's an error, you can't do any undefined operations.
Ah, got it. It's just that everywhere else you say Error, and 'only defined if' brings visions of C and nasal demons.
Haha, fair enough, I'll clarify the wording.
I think we should get some input from some other rockstarians, but then I would be willing to make this a PR to the spec.
Added operator precedence stuff.
I'm completely on board with this definition of types and typing in Rockstar
Can you add some rockstar example snippets?
Can you also call out where equality is
and is as high/low
fits into this picture? How strict should it be?
How are leading zeros, commas, e notation handled if in the string?
"010" is 10
outputs true/false? (some languages see "010" as octal, e.g. 8)"10,000" is 10000
OR "10.000" is 10000
outputs true/false? (assuming the conversion uses default from_string logic from: http://www.dec64.com/dec64_string.html)@kentros Updated it with better language and examples.
@cwfitzgerald Did I miss the PR for this? I don't see one.
(Edit: NVM, #131.)
@wolfgang42 #131
For string concatenation, I expected one of the following to work, but I couldn't figure it out after reading through the docs, watching the Youtube video on FizzBuzz guitar rock (fun times!), or just playing with the REPL at codewithrockstar
Example is one
My cat is "left" plus "right"
Another Example is Two,
My cat says left,
My dog says right,
My pets is my cat with my dog,
Whisper my pets.
How are you all doing string concatenation? I am thinking maybe doing something with stack, arrays or redirecting back and forth from STDIN and STIOUT may be possible, but seems too convoluted.
It would be a good idea to clarify if Rockstar is weakly or strongly typed.
Specifically:
For example, can I do this?
stdin: "5" stdout: "I love 6"