6 ms·
[FWIW, dev work on this was started 7 yrs ago and ended 4 years ago.] I like many features of this language -- although the feature I don't like is traits/mixin
by thelazydogsback 7y ago
[FWIW, dev work on this was started 7 yrs ago and ended 4 years ago.]
I like many features of this language -- although the feature I don't like is traits/mixins (one of the lang's central tenants), which seems like a bad idea in the general case -- it makes implementation inheritance even more abusable, rather than preferring delegation.
"hello" print
in addition to
someObj.ToString()
in Java-esque languages are just horrible, IMHO.
An arbitrary object should have absolutely no business knowing how to render itself, nor should a string know how to do I/O on itself, as these operations depend on the context of their usage.
Rather, for example, if you want to stick with message-sends:
console [print "foo"]
would delegate the printing of "foo" to the console object.
(here the brackets reify the message -- not sure about the syntax in Potion.
I can't tell you how many time in my code or in others', a .ToString() was expected to do one thing (pretty-print, for example) when instead it used some default method, such as the base method that prints " <a Foo>" or something. These things even end up in production output.
- dmix 7y ago> I can't tell you how many time in my code or in others', a .ToString() was expected to do one thing (pretty-print, for example) I'd expect this to turn the object into a String.
- thelazydogsback 7y agoSure. What kind of string? For debugging? If so, is a recursive? For output to a log? For output to a widget in a UI? To a string suitable for a report? What encoding? What language?
- earenndil 7y agoWhy not add an expectation, then, for what kind of string it is? You just have to have one. E.G. perl has .perl, which has the constraint that, for any obj, it should be that obj == (EVAL obj.perl). It doesn't matter what that is, as long as you agree on it. Having objects that know how to print themselves isn't intrinsically problematic.
- thelazydogsback 7y agoThat is serialization, which is one purpose for converting to a string. Dynamic languages already tend to be able to print objects in a way that's meaningful -- such as most REPL-based languages that have a reader (or eval) and a printer. As do ML-derived languages the print in constructor format, but they tend not to have readers or eval. Having it called .perl in this case is already a step in the right direction from toString, as you know what its for.
- ludamad 7y agoThat's almost comically underspecified. One big concern that comes to mind, is the string a complete view of the object (and thus suitable for serialization) or not? Or is it more succinct and suitable for a print statement?
- dmix 7y agoYes, I get the Java stuff, I was being sarcastic because it totally missed the context it was built with, in favour of some generalist mainstream adoption critique which misses the point. Have you seen the homepage? The Potion Pledge "everything is an object" bit was a good hint.
- smilekzs 7y agoContext: I write C++ at work. I also worked on compile-to-js language in the past. > An arbitrary object should have absolutely no business knowing how to render itself What should, in your opinion? I find it straightforward to implement even plural serialize-to-string operations within classes or at least the same module as the class. One example that immediately comes to mind is a quaternion that can print itself as either 4 numbers (raw) or 3 numbers (euler angles). That said in C++ you don't have a standard `ToString`; you do have a standard shift-to-ostream that serves the same purpose. Rust also has Display and Debug traits you can implement, which I guess makes more sense to me than a single `ToString` as it resolves a common ambiguity. Anything further than string/debug-print, though, I think your objection makes more sense, as "render" (as in "to HTML" and such) is more cross-concerns; in these cases I usually opt for "function in the same package as the class, but a separate source file". > nor should a string know how to do I/O on itself But isn't this a different issue compared to the previous case? The representation of "a string" is public knowledge while that of "an arbitrary object" is not.
- thelazydogsback 7y ago> ... a quaternion that can print itself as either 4 numbers (raw) or 3 numbers (euler angles). Then at last you presumably have overloads that are descriptive, such as .ToRawString() and .ToEulerString(), correct? If you did a cout<<q, which one are you going to get? Having a non-abstract base .ToString() defined in Object (and that requires no format parameters) causes the issues. Of course you could define an enum and take it as a format, like .ToString(Format.Euler), but even if you define well-named overloads, the other .ToString() is still hanging there and probably doesn't do anything useful. So, for most cases in most current language, my statement was probably a bit strong and should be weakened to "the framework should not assume there is one best/default way to render any Object to a string regardless of context and purpose and offer a default implementation at the top of the hierarchy". Ultimately, however, I think the stronger argument does hold, but is not easily addressed in most languages, or at least is not addressed in any consistent to concise way across many languages.
- jcelerier 7y ago
- seanmcdirmid 7y agoObjects knowing how to render themselves is great for debugging. In fact, many of us see toString just as a debugging function, and nothing meant for end-user presentation in non-debug console output.
- ludamad 7y agoI agree, generally. For that, I like Python's "repr" concept. A debug format should, in my opinion, match the definition syntax and be largely be handled by the language.
- zvrba 7y ago> An arbitrary object should have absolutely no business knowing how to render itself, Well, `toStrig` and its inverse make sense mostly for value types and these usually have ONE canonical representation. SQL has been based on converting values to/from strings since... always. E.g., when I want to insert a GUID into a table in SQLServer, I send it in as a... string. JDBC driver returns it as a string as well. Problems with string conversions arise when a value type doesn't have a single canonical representation, e.g., dates and times.
- rurban 7y agodev work didn't stopped 4 years ago, it's just not main priority anymore, and I'm blocked on two major things. (see below) console "foo" print would be the potion syntax, if console would exist as IO object. just compare to smalltalk, forth or ruby with smalltalk syntax. print is not used as serialization method, and not used as pprint. pprint would be the proper pretty-printing extension over print, and dump is the default serializer. I don't get the problem with "hello" print. It's not comparable to someObj.ToString(). The potion equivalent would rather be hello string vs hello dump vs hello pprint.
- thelazydogsback 7y ago> console "foo" print Sorry if I misunderstand -- Wouldn't this send "foo" to the console object (which it probably wouldn't understand), and then send "print" to whatever that returned, which isn't what you want? You don't want to send "print" to "foo" first and then send that to the console either. You want to send the message [print "foo"] to the console object - you are delegating the action. [Using ST syntax] If you wanted to do it w/o a reified message, you could do: console print "foo" Where "print" is really "get-default-printer-object" which uses something like doesNotUnderstand to respond to "foo" as a message, or console print: "foo" As a keyword send, or to combine the approaches somewhat: (console stdio-printer) print: "foo". I will RTFM again so I can get a better handle on the Potion syntax - unlike ST which I'm more used to, it's not as clear to me yet at first glance what is a msg and what is an arg.