Closed g4s8 closed 3 years ago
@g4s8 I vote for everything be an object. So, your approach 42.string() returns "42", makes sense to me.
0.5.string()
and .5.string()
as well? I guess that is the only tricky bit.. but we don't need to require a one-letter look ahead.
@fabriciofx Why would you ever actually use 42.string()
? (Except perhaps to demo the language in a REPL or something?) Why not just write "42"
? It's quicker.
Would you also write "42".int()
when you wanted 42?
@pa9ey
I was thinking in something like:
m(int x) {
x.string();
}
What do you think?
@fabriciofx That's not a literal. :)
@g4s8 yes, we definitely need literals, but I don't like the dot-notation. Instead of 42.string()
I would rather have string: 42
.
As of literals, I guess, we need:
"Hello, world!"
-> text
(n bytes)123
-> int
(4 bytes)3.1415926
-> double
(8 bytes)'&'
-> char
(1 byte)What else?
@yegor256 Sure we need literals! But the main question was can you call methods on them. You don't seem to have addressed that.
Are literal string values/arguments of type Text
or String
? Can you specialise a literal object? I think that could get weird..
Perhaps we can avoid literal method calls and object specialisation by saying that the literal will be of "native types" (e.g. int
rather than Integer
) and will be auto-casted to their corresponding type when passed as an argument.
Do we need literals beyond arguments, e.g. when @assigning
within a constructor? The primary constructor should not use a hard-coded literal!
@yegor256 What's the problem with dot-notation? Why you don't like it?
@pa9ey What's a literal to you? To me, is a special case of variable. So, if I can do a x.string()
to a variable, makes sense to me do a 42.string()
to a literal too. What's your opinion?
@fabriciofx I'm not particularly trying to express (or even have) an opinion. I just asked a bunch of questions. (Specifically about calling methods on literals.)
If you want my answers to those questions, well I already hinted at a possible answer to Q1. My answer to Q2 is: I can't think of a reason why not. My answer to Q3 is: No.
I like @stain's question too:
Do we need literals beyond arguments, e.g. when @assigning within a constructor? The primary constructor should not use a hard-coded literal!
It seems to me we don't.
This question is not about "why to use 42.string()?", but "are we able to call literals methods?"
@yegor256,
Instead of 42.string() I would rather have string: 42.
I agree with this, but in example you create new object instead of calling method.
@stain, I think you are right. If we allow literals only as constructor/method parameter, we'll solve loads of problems.
@pa9ey, you may want to use (42.0).string(locale)
, this return different string for some locales.
@g4s8
This question is not about "why to use 42.string()?", but "are we able to call literals methods?"
Interesting. I think that for every question "Are we going to put x in the language?" one of the first questions we should ask is "Why would you want x in the language?".
Maybe not explicitly ask it, but we should always be considering that question. This seems to me to be a fundamental principle of all software development, not just languages and compilers.
Also, your replies to @stain and to me seem to contradict each other.
I think you are right. If we allow literals only as constructor/method parameter, we'll solve loads of problems.
you may want to use (42.0).string(locale), this return different string for some locales.
@pa9ey, sorry for misunderstanding, I mean that I like idea when we use literals only in constructors and method params, but I can imagine how to use literals in method body.
Why would you want x in the language?
I think it's impossible now to specify each case where literals can be used. E.g. in 42.string()
they are redundunt, because we can replace it with "42"
, but what if integer type will provide another string
method, like string(Locale locale)
?
To answer this question (Why would you want x in the language?) we need full integer, string, etc. types declaration, because without concrete examples we may only make a gues about it.
@g4s8 Sure. But there's no need to guess. Let's wait till we need it rather than add it just in case.
@g4s8 @pa9ey @stain @fabriciofx I think that "calling a method" is something we should avoid in OOP. I'm not entirely sure, but that's what I feel. Calling a method means getting the result right now -- a procedural and imperative approach. While declaring a new object is declarative and object-oriented. Say, we need a string from a number. This is imperative:
text = number.string();
The calculation will happen right there, now, at the moment of calling method string()
. Here is a declarative way (not EO syntax):
text = new IntAsString(num);
Here we're declaring a new object, which behaves like text, but the calculation is not yet done. It will be done, maybe, later.
See the difference?
And I don't like this: 42.string()
. Even though Ruby is having that "syntax sugar", I would rather stay away from it. I'm in general against all "sugars" -- the stricter and simpler the code, the better.
See the difference?
@yegor256 Yes, but that's not really what this issue is about, and it's also quite confusing.
Where are you going with this? It doesn't stack up with what EO is currently about. For example, if there's no code in constructors and you can't call methods, then the objects will never actually do anything!
Here we're declaring a new object, which behaves like text...
If no method is ever called, it won't behave at all! :)
If no method is ever called, it won't behave at all! :)
@pa9ey well, look at this fibonacci number calculator:
object fibonacci(1) as Int:
Int @n
ctor():
fibonacci: 1
ctor(Int n)
Int int():
if:
firstIsLess: @n, 2
1,
plus:
@n
fibonacci:
minus: @n, 1
Not a single method was called, but the object is a fibonacci number. Pay attention, plus
and minus
are not methods, but object constructors. I'm not entire sure where I'm going with this :) But I think that we need as less method callings as possible. Most probably none. I'm thinking about it...
@yegor256 I like this idea (in theory) too. But I think this is the key issue I've been banging on about since before EO existed. I've posted this video before, somewhere in channel:
"Haskell is useless." https://www.youtube.com/watch?v=iSmkqocn0oQ
I think the EO that you're talking about is also "useless". (If you get my meaning.)
But at some point we have to address the "how do we also make it useful" question. We need a simple EO program, say, that asks the user for a digit (from 1 to 9) and then asks for another, and then outputs the sum of those two.
Then there will be methods. There will be behaviour.
If I was less "useless" myself, I would have written this by now. :)
@pa9ey I agree, there will be "methods", but they should not be called from object to object, only from decorator to encapsulated object. Take this as an example:
app:
printed:
sum:
input_as_int: "please, enter first digit"
input_as_int: "please, enter second digit"
We just create an app here, which is a copy of object app
. When it become "alive", it calls printed.asText()
, which calls sum.asText()
, which calls input_as_int.asText()
, which prints that intro message, and returns the value entered.
I'm against this:
Foo f = new Foo();
f.doIt(); // this is wrong
And I like this:
Bar b = new Bar() {
private Foo f;
void run() {
this.f.doIt(); // it's OK
}
}
Make sense?
@yegor256 I could be wrong but, as I understood, using this idea all objects will have only one method.
@yegor256 I just can't see it though. Too much is hidden in your example. It's not really input_as_int
either. It's more like user_query_as_int
. Which is an oddly specific and yet complex object.
You also see a hint of the procedural creeping in there, with the first input and then the second input. And isn't this unavoidable? What if you now extend this program to also ask for the operation. Add, subtract, multiply, divide.
I don't know. Maybe I've not even begun to grasp what we're aiming at here.
@g4s8 @mdbs99 @g4s8 I still think that we may introduce a rule: "an object A can call method M only if M belongs to object B, which is encapsulated by A." Think about it. I feel that it will solve a lot of problems in OOP. Suggested a discussion in our Gitter channel: https://gitter.im/yegor256/elegantobjects?at=588c6f985309d6b3587a7df9
@yegor256 As opposed to what? Do you mean you couldn't call methods on an object that has been passed in via a method? Only those passed in at construction, or created internally?
@yegor256 I considered this solution before and it won't solve any problems - in fact it will create an unworkable disaster. You are using messages like operation invocations. That is the problem. The issue you are concerned with, which is creating objects which are autonomous, can't be resolved in this matter. The heart of OOP, according to Kay, West, and EVERYONE who ever really did it, is communication between nodes in a network. That means passing messages between objects who are distinct, not vertically between sandwhich layers of a complex object.
What do you think about different aspect of literals: custom literals?
Shortly speaking, the idea is that semantics of custom literals (and probably built-in ones) is defined not by syntax, but by the style of literals. It also means that source code is not a plain text anymore, but since eolang is designed as a new language, maybe it's possible to apply unusual approaches?
The basis is the following: when a type is defined, a styled literal can be defined for the type. The same story as for built-in types and literals such as strings, bools or integers. Semantics of a literal is retrieved from its style. For example, strings do not require quotes to specify what chars a string consists of, and no escaping required.
Literals look like the following:
Do you mean, that we should format code by choosing it's font, colour and style?!
@pchmielowski
Do you mean, that we should format code by choosing it's font, colour and style?!
Yes, why not? Of course, there are pros and cons of the such approach, but I think proper tools can solve them. Modern programming languages adhere the principle "more expressiveness by less code", and styling provides additional dimension to plain text for specifying more sense without cutting syntax elements (I mean traditional ways like shorter keywords or mnemonic symbols).
The styling is a consequence of more general question: what do you think if source code is not a plain text, but tree-like construction? Not so radical such as AST, but some intermediate hybrid tree with text elements.
Tools like static analyzers, editors or compilers use AST to work with code. Only humans need text presentation to write and read the code. Moreover, we do already use tree-like approach when indent blocks and scopes in the code. So, can we remove text at all? Or at least partially? This will avoid us from hollywars like TAB vs SPACES or 2 vs 4 CHARS, which are the result of exactly textual presentation of the code. This gives us more power in semantics (like custom literals). Performance of practical tools can also be improved: phase of parsing becomes less expensive or missing at all since code tree is already available.
So, the styling is a way to specify the type of a node and render this type to humans reading.
@maxinovi I'm not sure I fully follow what you're talking about but it made me think of this: https://youtu.be/TS1lpKBMkgg?t=39m27s
Which I originally referenced here: https://github.com/yegor256/eo/issues/5
@pa9ey Yes, in general I agree with Paul's topic and his statement "I need a coherent set of tools for creating software", though in details and the reasons for the topic look different.
I'm going to join discussion in #5. Regarding this I have one question. I'm developing similar project for object-oriented modeling and tools, may I put a link to it as a comment in #5? Since you are collecting resources about language development.
@maxinovi It's Yegor you'd have to ask. But I don't see why you shouldn't post it. No harm in us knowing what's out there. :) That issue's a little dormant though. Not sure what to do with it.
@maxinovi sure, post a link, if it's relevant
@g4s8 yes, in EO numbers and strings are objects. You can do this:
[n] > f
5.add n
This will make 5 + n
.
How to use literals in EO? Are they objects too or not? If yes, can we call methods of them? E.g.:
42.string()
(returns "42")?