I've just read your post on multimethods and am glad to see language
development - it's evolving to something really nice.
But there is one small thing which bothers me. This one:
def (left) + (right) concatenate(left string, right string)
I've just updated interpreter and checked this out and indeed it works this way:
> "a" + 1
= a1
> [1, 2] + 1
= <List>1
I feel that this basically makes language have weak typing, as
JavaScript does. And in JS it's a major pain that when you append
something, you get something like that. So maybe + shouldn't be an
operation on anything. I know that's more or less high level behavior,
which is easy to change, but still this seems so wrong to me that I
decided it should be discussed.
And another thing, you can't write methods in REPL:
> def fib(0) 0
! Parse error: A method body must be a block.
And... maybe I'm blind, but is there any way to see all methods
defined on an object? Like dir(something) in Python.
--
Alexander
I've just read your post on multimethods and am glad to see language
development - it's evolving to something really nice.
> "a" + 1
= a1
> [1, 2] + 1
= <List>1
I feel that this basically makes language have weak typing, as
JavaScript does.
And another thing, you can't write methods in REPL:
> def fib(0) 0
! Parse error: A method body must be a block.
And... maybe I'm blind, but is there any way to see all methods
defined on an object? Like dir(something) in Python.
I think one right is restricting --if only by convention-- to given domains. In
particular, reserve + - * / ^ (power) to arithmetics / number types; and have
an operator dedicated to string concat only (I'll use ~).
Strings are special and complicated enough, and string concat so common, that I
guess it's really worth it. As a nice side-effect, since there is no ambiguity
thank to the operator beeing reserved (even if not concretely enforced), then
one can safely 'toString' operands:
"a" ~ 1 --> "a1"
[1, 2] ~ 1 --> "[1, 2]1"
>> And another thing, you can't write methods in REPL:
>>
>>> def fib(0) 0
>> ! Parse error: A method body must be a block.
>>
>
> You can, but the method syntax isn't exactly how I wrote it in the post. The
> current grammar doesn't allow single-line methods, so you have to do:
>
> def fib(0)
> 0
> end
>
> The reason is that getters don't have any separation between the the name
> and the body:
>
> def (n Int) negate - n // how do you tell that "negate" is the name and "-
> n" is the body?
>
> So they require a newline as the separate:
>
> def (n Int) negate
> - n
> end
>
> So, to be consistent, all methods do. This is one my list of syntax problems
> to fix so if you have any ideas here I'd definitely like to hear them.
What about replacing newline by "do"?
A better solution imo is getting rid alltogether with this exceptional syntax
for func defs and only keep the regular:
negate = fn (n Int) - n ' guess there is no need for "end" here?
negate = fn (n Int)
- n
end
I guess in programming language design all non absolutely necessary occurrences
of alternatives are wrong; if only, because people tend to expect different
idioms to have different meanings (esp in computing, unlike in natural
languages). Here, the cost is five easy to type characters: " = fn ".
denis
--
_________________
vita es estrany
spir.wikidot.com
I think one right is restricting --if only by convention-- to given domains. In particular, reserve + - * / ^ (power) to arithmetics / number types; and have an operator dedicated to string concat only (I'll use ~).
Strings are special and complicated enough, and string concat so common, that I guess it's really worth it. As a nice side-effect, since there is no ambiguity thank to the operator beeing reserved (even if not concretely enforced), then one can safely 'toString' operands:
"a" ~ 1 --> "a1"
[1, 2] ~ 1 --> "[1, 2]1"
What about replacing newline by "do"?
A better solution imo is getting rid alltogether with this exceptional syntax for func defs and only keep the regular:
negate = fn (n Int) - n ' guess there is no need for "end" here?
negate = fn (n Int)
- n
end
I guess in programming language design all non absolutely necessary occurrences of alternatives are wrong; if only, because people tend to expect different idioms to have different meanings (esp in computing, unlike in natural languages). Here, the cost is five easy to type characters: " = fn ".
Well, I'd personally prefer if it would be (by default, since you can
override anything in your application) as it is in Python [1]: you can
add numbers, concatenate strings and lists (strings with strings and
string with lists), and... that's all? Maybe, hashes and sets, but not
lists and numbers. Just because it makes much more sense to make it
explicit when you want to concatenate string representations of some
objects rather than objects. JS proves that this behavior can make you
cry sometimes. :)
[1]: I think this part is done in a right way in Python
> A lot of this is stuff that still needs to be figured out and stuff that
> really excites me. Part of the reason I started Magpie is because I really
> like API design and was frustrated by what existing languages let me
> express, so it'll be interesting to figure out what good design looks like
> in a language with multimethods.
I completely agree, but in other way if you have all-consuming
concatenation operator, you'll have a lot of strange effects (in other
words: hard to catch bugs) when you're not paying attention enough to
not concatenate objects which can be concatenated only with this
general '+'.
> You can, but the method syntax isn't exactly how I wrote it in the post. The
> current grammar doesn't allow single-line methods, so you have to do:
Ah, ok, no problems then. I just thought they do exist but not in REPL.
> The reason is that getters don't have any separation between the the name
> and the body:
>
> def (n Int) negate - n // how do you tell that "negate" is the name and "-
> n" is the body?
>
> So they require a newline as the separate:
>
> def (n Int) negate
> - n
> end
>
> So, to be consistent, all methods do. This is one my list of syntax problems
> to fix so if you have any ideas here I'd definitely like to hear them.
Eh, not much. Given that my main language is python, colon comes to
mind, but it doesn't really suit language well (or does it?). But some
separator probably should be invented since single-line functions can
be terribly useful. :))
>> And... maybe I'm blind, but is there any way to see all methods
>> defined on an object? Like dir(something) in Python.
>
> Heh, nope, not yet. Things are still very primitive so there isn't much
> helpful functionality yet. :)
Hehe, it's just convenient method to explore language. Though magpie
is mostly written in magpie, so I just need to pour in sources. :)
--
Alexander
Well, I'd personally prefer if it would be (by default, since you canoverride anything in your application) as it is in Python [1]: you can
add numbers, concatenate strings and lists (strings with strings and
string with lists), and... that's all?
Eh, not much. Given that my main language is python, colon comes to
mind, but it doesn't really suit language well (or does it?).
But some
separator probably should be invented since single-line functions can
be terribly useful. :))
> What about replacing newline by "do"?
>>
>
> Interesting idea:
>
> def (_ IndexableIterator) current do this indexable[this index]
>
> I still find that a bit hard to read since "do" is also the beginning of a
> valid expression.
>
>
>> A better solution imo is getting rid alltogether with this exceptional
>> syntax for func defs and only keep the regular:
>>
>> negate = fn (n Int) - n ' guess there is no need for "end" here?
>> negate = fn (n Int)
>> - n
>> end
>>
>
> Magpie does have functions like that, but multimethods are not just
> variables (in fact, they occupy a separate namespace, which may or may not
> be a good idea).
>
> I'd find the above confusing because "=" *replaces* a variable in other
> cases, but here it would *merge* two method definitions.
Sorry, I'm unsure of syntax but I guess it should have used the "var" prefix"
to introduce a /new/ element:
var somefunc = fn (...) ...
By the way, I take the opportunity to tell that, imo, the distinction between
variable *creation* (with var) and *change* (without it) is a Very Good Thing
(even wrote an article on this topic:
http://spir.wikidot.com/create-vs-change). In my project, the following signs
are used:
n : 1
n := 2
There is a third assignment sign used to replace a referenced thing:
ref := someState ' changes the thing's state
ref :== someThing ' replaces the thing itself
Since, '=' is not an assignment, it is free to compare values by equality; '=='
instead compares things by "unicity" (identity, like python 'is'). A nice
side-effect is the parallel:
x := v --> x = v
x :== t --> x == t
> It also isn't clear
> how all flavors of methods would be defined like that:
>
> 1. Getters where there is an argument to the left but not to the right:
> "string" count
> 2. "Function-like" method where there is only an argument on the right:
> print("hi")
> 3. Full methods with args on both sides: list add("item")
>
> I guess in programming language design all non absolutely necessary
>> occurrences of alternatives are wrong; if only, because people tend to
>> expect different idioms to have different meanings (esp in computing, unlike
>> in natural languages). Here, the cost is five easy to type characters: " =
>> fn ".
>>
>
> The above syntax is actually a valid way to define a function and assign it
> to a variable. Right now, Magpie has both functions and methods and the two
> aren't exactly the same. Functions are first-class and anonymous where
> methods are always named and not first class. (To make a method first class,
> you'd wrap it in a function.) There are, I think, reasonable but obscure
> reasons for the distinction that I can go into if you're interested.
Right, thanks for the explanation. Maybe we come back to this later (when my
exploration of Magpie's world has progressed -- I've not yet reached the OO level).
Denis
That's an annoying syntax design problem. I guess since newlines seem to deal
as instruction (statement/expression) separators in Magpie and to separate a
header from its block (at least for func defs), you may need a visible
separator (1) for multi-instruction lines (2) to allow a single-line func body
on the same line as its header.
(2) is annoying especially if the problem happens only for func defs. You'd
need something for func defs playing the role 'then' plays for conditionals.
For regularity, it should also be a key word, not a sign. For regularity too,
it may be good to have it also in multiline func defs! (like then')
Said differently, each block construct should have its "introductory keyword".
(But the same keyword may deal for several constructs, like 'do' for different
loop kinds.)
Another route may be to get rid of such introductory keywords for all
header+block constructs and do it the python way: indented structure instead of
delimited structure. But I guess that's not your style...
By the way, I take the opportunity to tell that, imo, the distinction between variable *creation* (with var) and *change* (without it) is a Very Good Thing (even wrote an article on this topic: http://spir.wikidot.com/create-vs-change). In my project, the following signs are used:
n : 1
n := 2
There is a third assignment sign used to replace a referenced thing:
ref := someState ' changes the thing's state
ref :== someThing ' replaces the thing itself
Right, thanks for the explanation. Maybe we come back to this later (when my exploration of Magpie's world has progressed -- I've not yet reached the OO level).
On 04/21/2011 10:41 PM, Alexander Solovyov wrote:That's an annoying syntax design problem. I guess since newlines seem to deal as instruction (statement/expression) separators in Magpie and to separate a header from its block (at least for func defs)
So, to be consistent, all methods do. This is one my list of syntax problemsEh, not much. Given that my main language is python, colon comes to
> to fix so if you have any ideas here I'd definitely like to hear them.
mind, but it doesn't really suit language well (or does it?). But some
separator probably should be invented since single-line functions can
be terribly useful. :))
, you may need a visible separator (1) for multi-instruction lines (2) to allow a single-line func body on the same line as its header.
(2) is annoying especially if the problem happens only for func defs. You'd need something for func defs playing the role 'then' plays for conditionals.
For regularity, it should also be a key word, not a sign. For regularity too, it may be good to have it also in multiline func defs! (like then')
Said differently, each block construct should have its "introductory keyword". (But the same keyword may deal for several constructs, like 'do' for different loop kinds.)
Another route may be to get rid of such introductory keywords for all header+block constructs and do it the python way: indented structure instead of delimited structure. But I guess that's not your style...
> "a" + 1
= a1
> [1, 2] + 1
= <List>1
I feel that this basically makes language have weak typing, as
JavaScript does.
That's a good point. All this stuff is brand new, so I'm still working things out. I think the question here is what did the programmer intend when they did "[1, 2] + 1"? If the answer is they wanted to concatenate an item to the list, then we should probably just define:
def (list List) + (item) list add(item)
If the answer is that it was an error, then we should tighten the default "+" to not allow any type. We could do something like:
def (left Stringable) + (right Stringable) concatenate(left string, right string)
The strictest option would be no default "+" at all, and instead we'd define specific methods for each pair we wanted to allow (string+string, int+string, string+int, etc.) I'm not sure if the combinatorial explosion would be a pain or not though.
A lot of this is stuff that still needs to be figured out and stuff that really excites me. Part of the reason I started Magpie is because I really like API design and was frustrated by what existing languages let me express, so it'll be interesting to figure out what good design looks like in a language with multimethods.