Talk:Infinite Vector

From Esolang
Jump to navigation Jump to search

Some of your data type names are rather funny. --SuperJedi224 (talk) 13:22, 17 October 2015 (UTC)

I actually have serious doubts about how easy 128-bit and 256-bit integers will be to implement, but calling a type "longer long" was just too good an opportunity to pass up. --ais523 03:58, 20 October 2015 (UTC)

Very first implementation and thereby encountered issues

I am in the process of implementing this language in Rust (albeit slowly because I got other things to do) and found several flaws in both the language and its specification. Adding more pieces of information to the specification (the wiki page) might solve most of them though. So here we go:

  • (major flaw) The language offers a great amount of operations on vectors — but none to contruct them in the first place. This issue could very well be rooted in the vague specification of variables: Does the first reference of an undeclared variable throw an error or does it define it to be an empty vector … but then, of what type? If the latter is not the case, then the only pre-defined variable is input … and maybe also output (unspecified)? But the value of input is obviously unknown, there is no way to use it as a means to construct new (e.g. empty) vectors from it and get a deterministic result. One solution would pre-define the variables null_short, null_long_long, etcetera to be empty vectors of the respective type. Another one would introduce new syntax like 5 (chapter) 9 which builds a chapter-vector of length 5 with all elements set to 9. Of course, there are many more.
  • (major flaw) The specification (source) requires the vector type of input to be inferable from the program's code. This is impossible because there is no command that only works on e.g. type short. The best it can get are operations that only work on floating-point vectors — from which there are 3 types. You also cannot annotate the type, only cast to one (an implementation could use the latter to "infer" input this way). The only thing known to the compiler about input is its length because literals (e.g. if typed into the command line as program arguments) do not contain information about their concrete type (more on that right below).
  • The syntax of (number) literals is heavily underspecified. I am fairly certain that the author wants integers to be of the form [0-9]+ save that the job of the specification is to clear up those bits. More importantly, floating-point literals: Does it allow scientific notation (via [eE][+-]?)? What about leading/trailing dots (.5, 5.)? Is 1.0 always floating-point (meaning can it only be used in contexts where floats are expected)? Is 1 always an integer? And finally as mentioned before, there is no syntax for annotating the concrete type of a literal (e.g. 7cp where cp stands for chapter) which seems necessary.
  • It's left unspecified how the widening multiplication * on chapter and long long long should be handled (my implementation errors).
  • The definition of program output is pretty vague: Should it write to stdout? How does the text representation look like in this case?
  • The concrete type of the right operand of the shift operations (the shift amount) is left untold. It states only unsigned integer types being valid but hey, literals are overloaded: On input like r = l << 90000, the implementor does not know how much stack or heap space it should allocate for 90000, always doing 256 bits (because literals of type chapter should be permitted in this context) no matter what, is a little saddening to me and my memory because most of the time, the amount will fit in 8 bits.
  • (minor) No comment syntax.

Implementing half-precision floating-point and 128/256-bit (un-)signed integers is easy in Rust by the way.
Another thing I personally did not understand is the definition of *+, although I probably just need to re-read it several times. It might be interesting for others how I named some of the arithmetic operators: + is wrapping addition, +? is saturating addition, *- is wrapping multiplication and * is widening multiplication. Except for widening, I took the naming scheme of Rust (and hope its accurate, please correct me if the operations do not correspond to Rust's provided methods). In my holy opinion, these terms should be mentioned on the wiki page.

Fmease (talk) 15:59, 24 March 2019 (UTC)

I probably released this language before it was ready. Then I forgot about it. So I'm not surprised there are problems with it!
  • In terms of the constructing-vectors issue, I was mostly thinking in terms of operating on the input vector, but you're right that concrete vectors specified in the program may be useful. I added a syntax to initialize vectors during the first loop, with explicit type and length; that fits with the rest of the language, and should be sufficient to solve the problem.
  • Using type inference everywhere without any way to actually set the types was almost certainly an oversight. I changed the way the type of the input is determined to be more explicit.
  • With these changes, there should no longer be a need for concrete types for literals (assuming that everything is initialized to some type, you can then infer everything). As such, it makes sense to allow integer-looking values to be used for implicit float vectors. The reverse would be a bit silly; it's an esolang, but the language already has enough silliness-for-the-sake-of-it, so it'd be perfectly reasonable for an implementation to disallow 1.0 as an integer.
  • Widening multiplication on a max-width type is an error, yes.
  • For this language, I'm treating I/O as being something that's external to the program, so different implementations could plausibly do it in different ways (e.g. via an FFI to another language). Using stdin and stdout is definitely sensible, though.
  • Sometimes esolangs allow for a natural comment syntax based on how the rest of the language works, but this one doesn't really. It wouldn't be too hard to add one, but I don't have any particularly interesting ideas for one.
As for *+, you can see it as multiplication followed by taking the top half of the result (*- is multiplication followed by taking the bottom half of the result, which happens to be equivalent to wrapping multiplication). I'm not sure if this way of thinking about it is more or less helpful than the common "wrapping"/"saturating" names. --ais523 17:28, 24 March 2019 (UTC)