Вы находитесь на странице: 1из 5

search

explain this behavior for me


 Moderated

jzakiya 1  9d

Nim 0.17.2 and 0.18.0

These compile and work fine.

r.inc; if r == rscnt; (r = 0, modk = modpg)


r += 1; if r == rscnt; (r = 0, modk = modpg)

But these throw an error.

if r.inc == rscnt; (r = 0, modk = modpg)


if (r.inc) == rscnt; (r = 0, modk = modpg)
if (r += 1) == rscnt; (r = 0, modk = modpg)

twinprimes_test6yc2.nim(158, 17) Error: type mismatch: got <void, int>


but expected one of:
proc `==`(x, y: int8): bool
first type mismatch at position: 1
required type: int8
but expression 'r += 1' is of type: void
proc `==`(x, y: int32): bool
first type mismatch at position: 1
required type: int32
but expression 'r += 1' is of type: void
proc `==`(x, y: int): bool
first type mismatch at position: 1
required type: int
but expression 'r += 1' is of type: void
proc `==`(a, b: Time): bool
first type mismatch at position: 1
required type: Time
but expression 'r += 1' is of type: void
proc `==`[T](x, y: set[T]): bool
first type mismatch at position: 1
required type: set[T]
but expression 'r += 1' is of type: void
proc `==`(x, y: pointer): bool
first type mismatch at position: 1
required type: pointer
but expression 'r += 1' is of type: void
proc `==`(x, y: char): bool
first type mismatch at position: 1
required type: char
but expression 'r += 1' is of type: void
proc `==`[T](x, y: seq[T]): bool
first type mismatch at position: 1
required type: seq[T]
but expression 'r += 1' is of type: void
proc `==`[T: tuple |
object](x, y: T): bool
first type mismatch at position: 1
required type: T: tuple or object
but expression 'r += 1' is of type: void
proc `==`(x, y: cstring): bool
first type mismatch at position: 1
required type: cstring
but expression 'r += 1' is of type: void
proc `==`(x, y: float): bool
first type mismatch at position: 1
required type: float
but expression 'r += 1' is of type: void
proc `==`[T](x, y: ref T): bool
first type mismatch at position: 1
required type: ref T
but expression 'r += 1' is of type: void
proc `==`[T: proc](x, y: T): bool
first type mismatch at position: 1
required type: T: proc
but expression 'r += 1' is of type: void
proc `==`(x, y: float32): bool
first type mismatch at position: 1
required type: float32
but expression 'r += 1' is of type: void
proc `==`[I, T](x, y: array[I, T]): bool
first type mismatch at position: 1
required type: array[I, T]
but expression 'r += 1' is of type: void
proc `==`(x, y: int16): bool
first type mismatch at position: 1
required type: int16
but expression 'r += 1' is of type: void
proc `==`(x, y: string): bool
first type mismatch at position: 1
required type: string
but expression 'r += 1' is of type: void
proc `==`(x, y: bool): bool
first type mismatch at position: 1
required type: bool
but expression 'r += 1' is of type: void
proc `==`[T: SomeUnsignedInt](x, y: T): bool
first type mismatch at position: 1
required type: T: SomeUnsignedInt
but expression 'r += 1' is of type: void
proc `==`(x, y: int64): bool
first type mismatch at position: 1
required type: int64
but expression 'r += 1' is of type: void
proc `==`(zone1, zone2: Timezone): bool
first type mismatch at position: 1
required type: Timezone
but expression 'r += 1' is of type: void
proc `==`[Enum: enum](x, y: Enum): bool
first type mismatch at position: 1
required type: Enum: enum
but expression 'r += 1' is of type: void
proc `==`(err1, err2: OSErrorCode): bool
first type mismatch at position: 1
required type: OSErrorCode
but expression 'r += 1' is of type: void
proc `==`[T](x, y: ptr T): bool
first type mismatch at position: 1
required type: ptr T
but expression 'r += 1' is of type: void

expression: r += 1 ==
rscnt

I do this nesting in Ruby, Crystal, et al, with no problem.

Is this a bug, or something that the Nim compiler should be able to figure out?

    Reply

miran  @jzakiya 9d

The first line of the error message ﴾ Error: type mismatch: got <void, int> ﴿ gives you a clue.

r.inc ﴾and r += 1 too﴿ increments r in‐place and returns void . After that, you are trying to see if that void is equal to
rscnt which is int .

You have already solved this ‐ use the first version. First increment, then compare.

  Reply

Araq  9d

I do this nesting in Ruby, Crystal, et al, with no problem.

And Swift deprecated ++ because it's bad. ;‐﴿

  Reply

dom96   @jzakiya 8d

These compile and work fine.

This is off‐topic, but do they really? I'm surprised to see that an if statement followed by a ; compiles.

  Reply

jzakiya 1  8d

First, I made a typo in rewriting the example code, it should have been a colon : not a ; after ... == rscnt: ...

So, OK. It was nonintutive for r.inc to return a void instead of its value. However, using this information, the following
code compiles, but it's oh so ugly. :‐﴾

if (r.inc; r) == rscnt: (r = 0; modk += md; k.inc)

I think the interpreter|compiler can be made smart enough to intuite in this context that what is desired here is the value of
the result of the r.inc operation. It would certainly make it compatible with other languages, and just make programmers
lives happier. :‐﴿

    Reply
Araq  8d

That's just your opinion, I think if (r.inc; r) == ... is fine and definitely better than having inc return the value.
"compatible with other languages" is always to be traded against "copying bad design is not good design".
3  Reply

jyapayne  @jzakiya 2  8d

If you'd like it to be more pretty, just use a template! A simple one like this would do:

Nim
template incr(r: var int): int =
r.inc
r

And then what you did should work if you replace r.inc with r.incr .

Edit: I typed this on my phone, so it may need some tweaking :P

Edit: Yep! Needs a var int. Updated code!

2  Reply

dom96  1  8d

I agree with @Araq . Being explicit here is better than this implicit behaviour that other languages have.
  Reply

jzakiya 2d

These questions are meant to assess technical clarity, and I see them as Yes|No answers. If any answer is No, can you
provide a technical basis for it.

1﴿ Unambiguous intent

Can we agree the operational intent of these phrases are clear?

if r.inc == rescnt: ‐‐ while index.dec > indx: ‐‐ num.inc + gcd(c,y)/par.dec

2﴿ Technical Capability

Isn't it straightforward to have the interpreter|compiler parse r.inc -> (r.inc; r) , etc if that's what needed for the AST,
etc?

    Reply

mashingan  @jzakiya 2d

Simple answer

1. No

2. No

Detailed answer

r.inc == rescnt

This is not clear because in the left side, it's mutating operation and the right‐side has simple value. Of course mutating
operation/function can have a return value but it's then too ambiguous to reason.

index.dec > indx

Same reason, mutating operation is just that unreasonable that Haskell have them done in Monad instead of pure function.
cmiiw

Isn't it straightforward to have the interpreter|compiler parse r.inc ‐> ﴾r.inc; r﴿

Explicit is better than implicit, on the right side it's obvious we send r after mutating it instead of the left, we just simply
mutating it. If it's in concurrent world, we can have r.inc to return bool to indicate we successfully mutate the value like
cas function. But returning bool different topic altogether.

It's better to differ mutating operations and pure operations.

  Reply

jzakiya 1  2d

Ah, you're doing what I hoped you wouldn't do, judging the outcome of the question and not the specifics technical
aspects, so let me try again.

1﴿ Unambiguous Intent

You see a program ﴾in whatever language﴿ which has these snippets:

if r.inc == rescnt: ‐‐ while index.dec > indx: ‐‐ num.inc + gcd(c,y)/par.dec


What do you think the programmer wants the program to do? Write what you think the snippet wants done in English.

Ex: if num.inc == 10:

Translation 1: if the incremented value of num equals 10 then do ....

Translation 2: increment num, and if that value is equal to 10 then do ....

2﴿ Technical Capability

I have demonstrated that the phrase:

r.inc == rscnt

will compile if replaced by

(r.inc; r) == rscnt

Without regard to whether you think it should|shouldn't be done is it technically possible to parse the phrase r.inc ->
(r.inc; r) , etc, when necessary so that it will compile appropriately to achieve programmatic intent?

    Reply

Araq  1  2d

Well you said it yourself, there is no unambiguous intent here, at least 2 different interpretations are possible. And if your
productivity depends so much on these shortcuts, create them for yourself. Others have already shown you how to do this
with today's Nim. Hint, it's possible with today's Nim, no language changes required, that implies it's "technically possible".
  Reply

jzakiya 1  2d

Well you said it yourself, there is no unambiguous intent here, at least 2 different interpretations are possible.

No. the two English translations of if num.inc == 10 are equivalent phrasings and unambiguous to an English speaker.
And you didn't present your English translations of any of the examples. So if you think they are ambiguous I am
interested in seeing what you ﴾anyone﴿ thinks those programming snippets are saying.

So, the examples in 1﴿ are clear and unambiguous as to programmatic intent.

Also Ruby, Crystal ﴾with Nim﴿ allow this programming style, but make it easy for programmers to do it.

Ruby: if (r += 1) == rescnt; .... end also (.....) if (r += 1) == rescnt

Crystal: if (r += 1) == rescnt; .... end also (.....) if (r += 1) == rescnt

Nim: if (r.inc; r) == rescnt: (....) also if (r += 1; r) == rescnt: (....)

So, in all three of these languages ﴾as a non exhaustive sample﴿ this programming paradigm is allowed and possible.
However, while Nim could also provide the syntactic sugar that Ruby, Crystal, et al provides, you insist to force the
programmer to become a manual parser to conform to your whims, than to provide the simple means to deal with these
cases, and make programmers lives easier.

Well, if you're going to force programmers to be compilers you can at least clearly document this for their benefit.

    Reply

Araq  2d

Well, if you're going to force programmers to be compilers you can at least clearly document this for their
benefit.

Yes, let's document the features that Nim does not have. Brilliant idea.

And again, here is the rest of my reply which you conveniently ignored so that you can continue to rumble on:

"And if your productivity depends so much on these shortcuts, create them for yourself. Others have already shown you
how to do this with today's Nim. Hint, it's possible with today's Nim, no language changes required, that implies it's
"technically possible"."

  Reply

dom96   @jzakiya 2  1d

No. the two English translations of if num.inc == 10 are equivalent phrasings and unambiguous to an English
speaker.

The two possible interpretations are:

(num.inc(); num) == 10

(let x = num; num.inc(); x) == 10

i.e. the 10 can be compared to the value before increment or the value after increment.

  Reply
Vantage 1d

In place change of data‐> return void, otherwise return value. If you want it another way use a library with your style of
programming. But its not good for this unambiguous functions to be in standard.

Nim
if (i.inc==10) or i.inc==23: echo "bla"

would increase the value twice for each check. Which wouldn't be as clear as separating the logic and the check.

  Reply

mashingan  @jzakiya 1d

judging the outcome of the question and not the specifics technical aspects

But I answered your question in technical aspects :﴾

We're talking about function operation here, we know two kind of operation, one that mutate and one that return value.

In order to avoid ambiguity, we have to differ those two kind of operations. In case of inc(x: var int) here, it's mutating
the x , so we can't return any value there.

Next question, why we can't? It's to avoid ambiguity. Can we do something about it? Yes, just make that inc(x: var int)
violate that difference and have it defined such as inc(x: var int): var int .

Unless for reason of performance and resource constraint, it's better to have pure functions as possible. Everyone who has
to read the code several months or years later will be grateful if you do it like that ;﴿

  Reply

Araq  1d

you insist to force the programmer to become a manual parser to conform to your whims, than to provide the
simple means to deal with these cases, and make programmers lives easier.

I checked your previous posts a bit. This was your last impertinence.

 Reply 1  Reply

Вам также может понравиться