ngs-lang / ngs

Next Generation Shell (NGS)
https://ngs-lang.org/
GNU General Public License v3.0
1.46k stars 41 forks source link

[FR] Autovivification #549

Closed rdje closed 2 years ago

rdje commented 2 years ago

The idea here is to be able to automatically build deeply nested data structures made of Arr and Hash for intermediate nodes. The leaves could be anything of course (Any).

Assuming z is a variable, writing

   z.a[7]{A}{B}{C}[8]{mykey}="Hello World"

would automatically create all the intermediate Arres and Hashes until reaching the final Hash with 'mykey' as key to store the "Hello World" Str.

Note that in the above example I am assuming that the things inside {...} are stringified.

No matter how it is actually done, the idea is to provide a way to create deeply nested data structures based on a few well known types (Arr and Hash here) by simply referencing the leaves starting from the top level variable and letting NGS figure out (DWIM) what the intermediates are (Arr, Hash or something else) and initializing them as appropriate.

I used autovivification systemacally when parsing files and storing the extracted information in a structured way using deeply nested data structure (DNDT) made of Perl5 lists and hashes without worrying about predefining and initializing all the intermediate nodes (list / hash).

I just relied on Perl5 to DWIM to help me with constructing my model view dynamically.

People will find their own use cases but the bottom line is to write things as if the referenced terminal leaves were already present, NGS would then fill the gap (DWIM) and build the route or path to reach those final or terminal leaves.

The way I see it is that autovivification may be seen as a generalization of the exemple you gave me when I asked in a previous post about how to define data/variable member of a type MyType, you answered by writing

t.anything = aValue, assuming t:MyType

Here 'anything' may literally be anything, from a simple identifier to an Arr element reference to a Hash element reference or even to a full-fledged autovivified path to a leaf node value.

ilyash-b commented 2 years ago

The idea here is to be able to automatically build deeply nested data structures made of Arr and Hash for intermediate nodes.

Sounds fine. In my opinion it should not be the default behavior as it can hide errors when you try to access something that you think should exist.

The way I see it is that autovivification may be seen as a generalization

I understand why but from my perspective it's very hard to see it the same way because right now it's special syntax E1.field_name = E2 and E1[E2] = E3.

Background

Design alternative 1 for discussion:

z.a[7]{A}{B}{C}[8]{mykey}="Hello World"

would be

z.deep_set(7, 'A', 'B', 'C', 8, 'mykey', "Hello World")

what I like about this solution is it does not involve any new syntax and should be relatively easy to implement. Up for discussion:


@rdje, let us know what you think

rdje commented 2 years ago

Hi Ilya,

I am totally fine with the deep_set() approach.

To me, it is the feature that is important, how it is implemented and presented to the user is a matter of taste and subject to debate. But overall the feature should be convenient to use.

In the past, I, myself, implemented the function approach even while working with Perl. I also started implementing it in Javascript. But of course these function implementations were less powerful than the Perl5 built-in feature. I only used Hashes as intermediate nodes.

The number of Hash keys and/or array indexes shall not be limited when using the deep_set() routine though.

In that sense, I agree that the parameter approach is less convenient, if we have to pick one approach over the other.

But I think we don't have to.

Arguments to deep_set() used to reference or build the path/route to the final or terminal leaves could be

The value to be assigned to the leaf node (RHS), that is, the rightmost argument (last) could be anything

In fact, since in code syntax any variable/value is a reference, or object instance, I didn't have to list the various kinds of values for RHS.

HTH -Richard

On Tue, 8 Feb 2022 at 10:26, Ilya Sher @.***> wrote:

The idea here is to be able to automatically build deeply nested data structures made of Arr and Hash for intermediate nodes.

Sounds fine. In my opinion it should not be the default behavior as it can hide errors when you try to access something that you think should exist.

The way I see it is that autovivification may be seen as a generalization

I understand why but from my perspective it's very hard to see it the same way because right now it's special syntax E1.field_name = E2 and E1[E2] = E3. Background

  • I am very reluctant to add new syntax in general. Let's put {key} aside for now?

Design alternative 1 for discussion:

z.a[7]{A}{B}{C}[8]{mykey}="Hello World"

would be

z.deep_set(7, 'A', 'B', 'C', 8, 'mykey', "Hello World")

what I like about this solution is it does not involve any new syntax and should be relatively easy to implement. Up for discussion:

  • The whole idea of having this facility as a function/method
  • The name deep_set
  • Parameters - maybe more idiomatic (but less convenient?) z.deep_set([7, 'A', 'B', 'C', 8, 'mykey'], "Hello World")
  • Return value: z or "Hello World" (z would be more idiomatic)

@rdje https://github.com/rdje, let us know what you think

— Reply to this email directly, view it on GitHub https://github.com/ngs-lang/ngs/issues/549#issuecomment-1032391841, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASSKVHGR54ADPGB3HGG4JZLU2DOUBANCNFSM5NXEW26Q . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

rdje commented 2 years ago

Ilya,

Returning the receiver (z) as the value of deep_set() would allow chaining. But if we stop there then the call shall not fire any error or warning.

But in some cases it might or would be interesting to return the RHS, "Hello World" in the exemple. Especially if that RHS has methods we would like to call.

More generally, we could be interested in chaining using the receiver (z) as context or the RHS (assigned value).

-Richard

On Tue, 8 Feb 2022 at 11:26, Richard DJE @.***> wrote:

Hi Ilya,

I am totally fine with the deep_set() approach.

To me, it is the feature that is important, how it is implemented and presented to the user is a matter of taste and subject to debate. But overall the feature should be convenient to use.

In the past, I, myself, implemented the function approach even while working with Perl. I also started implementing it in Javascript. But of course these function implementations were less powerful than the Perl5 built-in feature. I only used Hashes as intermediate nodes.

The number of Hash keys and/or array indexes shall not be limited when using the deep_set() routine though.

In that sense, I agree that the parameter approach is less convenient, if we have to pick one approach over the other.

But I think we don't have to.

Arguments to deep_set() used to reference or build the path/route to the final or terminal leaves could be

  • numbers, the corresponding intermediate node shall be an Arr
  • string, the corresponding intermediate node shall be a Hash
  • Arr containing numbers and strings whose content would then be expanded

The value to be assigned to the leaf node (RHS), that is, the rightmost argument (last) could be anything

  • scalar
    • number
    • Str
  • aggregate
    • Arr
    • Hash
    • Any (any object)

In fact, since in code syntax any variable/value is a reference, or object instance, I didn't have to list the various kinds of values for RHS.

HTH -Richard

On Tue, 8 Feb 2022 at 10:26, Ilya Sher @.***> wrote:

The idea here is to be able to automatically build deeply nested data structures made of Arr and Hash for intermediate nodes.

Sounds fine. In my opinion it should not be the default behavior as it can hide errors when you try to access something that you think should exist.

The way I see it is that autovivification may be seen as a generalization

I understand why but from my perspective it's very hard to see it the same way because right now it's special syntax E1.field_name = E2 and E1[E2] = E3. Background

  • I am very reluctant to add new syntax in general. Let's put {key} aside for now?

Design alternative 1 for discussion:

z.a[7]{A}{B}{C}[8]{mykey}="Hello World"

would be

z.deep_set(7, 'A', 'B', 'C', 8, 'mykey', "Hello World")

what I like about this solution is it does not involve any new syntax and should be relatively easy to implement. Up for discussion:

  • The whole idea of having this facility as a function/method
  • The name deep_set
  • Parameters - maybe more idiomatic (but less convenient?) z.deep_set([7, 'A', 'B', 'C', 8, 'mykey'], "Hello World")
  • Return value: z or "Hello World" (z would be more idiomatic)

@rdje https://github.com/rdje, let us know what you think

— Reply to this email directly, view it on GitHub https://github.com/ngs-lang/ngs/issues/549#issuecomment-1032391841, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASSKVHGR54ADPGB3HGG4JZLU2DOUBANCNFSM5NXEW26Q . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

rdje commented 2 years ago

Ilya,

We can think one step further and provide support for any types of aggregate intermediate nodes.

I started my proposal with Arr and Hash because that's what Perl5 allowed.

But I think if we are able to build DNDTs based on Arr and Hash it could be possible to do it with any types (built-in) of aggregate objects.

But the focus should be to have working it with Arr and Hash of course.

I raised that just to highlight the fact that we should not be constrained to only using Arr and Hash.

Not sure though if it would be wise to open this to user defined aggregate types as intermediate nodes.

-Richard

On Tue, 8 Feb 2022 at 11:40, Richard DJE @.***> wrote:

Ilya,

Returning the receiver (z) as the value of deep_set() would allow chaining. But if we stop there then the call shall not fire any error or warning.

But in some cases it might or would be interesting to return the RHS, "Hello World" in the exemple. Especially if that RHS has methods we would like to call.

More generally, we could be interested in chaining using the receiver (z) as context or the RHS (assigned value).

-Richard

On Tue, 8 Feb 2022 at 11:26, Richard DJE @.***> wrote:

Hi Ilya,

I am totally fine with the deep_set() approach.

To me, it is the feature that is important, how it is implemented and presented to the user is a matter of taste and subject to debate. But overall the feature should be convenient to use.

In the past, I, myself, implemented the function approach even while working with Perl. I also started implementing it in Javascript. But of course these function implementations were less powerful than the Perl5 built-in feature. I only used Hashes as intermediate nodes.

The number of Hash keys and/or array indexes shall not be limited when using the deep_set() routine though.

In that sense, I agree that the parameter approach is less convenient, if we have to pick one approach over the other.

But I think we don't have to.

Arguments to deep_set() used to reference or build the path/route to the final or terminal leaves could be

  • numbers, the corresponding intermediate node shall be an Arr
  • string, the corresponding intermediate node shall be a Hash
  • Arr containing numbers and strings whose content would then be expanded

The value to be assigned to the leaf node (RHS), that is, the rightmost argument (last) could be anything

  • scalar
    • number
    • Str
  • aggregate
    • Arr
    • Hash
    • Any (any object)

In fact, since in code syntax any variable/value is a reference, or object instance, I didn't have to list the various kinds of values for RHS.

HTH -Richard

On Tue, 8 Feb 2022 at 10:26, Ilya Sher @.***> wrote:

The idea here is to be able to automatically build deeply nested data structures made of Arr and Hash for intermediate nodes.

Sounds fine. In my opinion it should not be the default behavior as it can hide errors when you try to access something that you think should exist.

The way I see it is that autovivification may be seen as a generalization

I understand why but from my perspective it's very hard to see it the same way because right now it's special syntax E1.field_name = E2 and E1[E2] = E3. Background

  • I am very reluctant to add new syntax in general. Let's put {key} aside for now?

Design alternative 1 for discussion:

z.a[7]{A}{B}{C}[8]{mykey}="Hello World"

would be

z.deep_set(7, 'A', 'B', 'C', 8, 'mykey', "Hello World")

what I like about this solution is it does not involve any new syntax and should be relatively easy to implement. Up for discussion:

  • The whole idea of having this facility as a function/method
  • The name deep_set
  • Parameters - maybe more idiomatic (but less convenient?) z.deep_set([7, 'A', 'B', 'C', 8, 'mykey'], "Hello World")
  • Return value: z or "Hello World" (z would be more idiomatic)

@rdje https://github.com/rdje, let us know what you think

— Reply to this email directly, view it on GitHub https://github.com/ngs-lang/ngs/issues/549#issuecomment-1032391841, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASSKVHGR54ADPGB3HGG4JZLU2DOUBANCNFSM5NXEW26Q . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

rdje commented 2 years ago

Ilya,

Just more thoughts about deep_set().

Although I am 100% aligned with the use of a routine to build the route/path to reach the final/terminal node, I am not 100% certain using a routine with 'set' as a suffix is adequate.

The syntax version using [...] and {...} to decide which type of intermediate node (Arr=[...] or Hash={...}) we are using at each step doesn't infer anything about the type of access (set or get, read or write) we're attempting.

But using deep_set() already implies that we're about to set/write something.

I would be more inclined to use something less biased like

The idea is not to pre-determine the access type by having it in the name of the routine.

The routine should just return a reference to a variable of type Any, I am not sure about this though.

For example, if we use avv

1) z.avv("acountry", "acity", "astreet", anumber)

2) z.avv("acountry", "acity", "astreet", abuilding_number) = any_value

That is how I would do things, but I am not sure that is doable.

That's just a few ideas.

-Richard

On Tue, 8 Feb 2022 at 11:49, Richard DJE @.***> wrote:

Ilya,

We can think one step further and provide support for any types of aggregate intermediate nodes.

I started my proposal with Arr and Hash because that's what Perl5 allowed.

But I think if we are able to build DNDTs based on Arr and Hash it could be possible to do it with any types (built-in) of aggregate objects.

But the focus should be to have working it with Arr and Hash of course.

I raised that just to highlight the fact that we should not be constrained to only using Arr and Hash.

Not sure though if it would be wise to open this to user defined aggregate types as intermediate nodes.

-Richard

On Tue, 8 Feb 2022 at 11:40, Richard DJE @.***> wrote:

Ilya,

Returning the receiver (z) as the value of deep_set() would allow chaining. But if we stop there then the call shall not fire any error or warning.

But in some cases it might or would be interesting to return the RHS, "Hello World" in the exemple. Especially if that RHS has methods we would like to call.

More generally, we could be interested in chaining using the receiver (z) as context or the RHS (assigned value).

-Richard

On Tue, 8 Feb 2022 at 11:26, Richard DJE @.***> wrote:

Hi Ilya,

I am totally fine with the deep_set() approach.

To me, it is the feature that is important, how it is implemented and presented to the user is a matter of taste and subject to debate. But overall the feature should be convenient to use.

In the past, I, myself, implemented the function approach even while working with Perl. I also started implementing it in Javascript. But of course these function implementations were less powerful than the Perl5 built-in feature. I only used Hashes as intermediate nodes.

The number of Hash keys and/or array indexes shall not be limited when using the deep_set() routine though.

In that sense, I agree that the parameter approach is less convenient, if we have to pick one approach over the other.

But I think we don't have to.

Arguments to deep_set() used to reference or build the path/route to the final or terminal leaves could be

  • numbers, the corresponding intermediate node shall be an Arr
  • string, the corresponding intermediate node shall be a Hash
  • Arr containing numbers and strings whose content would then be expanded

The value to be assigned to the leaf node (RHS), that is, the rightmost argument (last) could be anything

  • scalar
    • number
    • Str
  • aggregate
    • Arr
    • Hash
    • Any (any object)

In fact, since in code syntax any variable/value is a reference, or object instance, I didn't have to list the various kinds of values for RHS.

HTH -Richard

On Tue, 8 Feb 2022 at 10:26, Ilya Sher @.***> wrote:

The idea here is to be able to automatically build deeply nested data structures made of Arr and Hash for intermediate nodes.

Sounds fine. In my opinion it should not be the default behavior as it can hide errors when you try to access something that you think should exist.

The way I see it is that autovivification may be seen as a generalization

I understand why but from my perspective it's very hard to see it the same way because right now it's special syntax E1.field_name = E2 and E1[E2] = E3. Background

  • I am very reluctant to add new syntax in general. Let's put {key} aside for now?

Design alternative 1 for discussion:

z.a[7]{A}{B}{C}[8]{mykey}="Hello World"

would be

z.deep_set(7, 'A', 'B', 'C', 8, 'mykey', "Hello World")

what I like about this solution is it does not involve any new syntax and should be relatively easy to implement. Up for discussion:

  • The whole idea of having this facility as a function/method
  • The name deep_set
  • Parameters - maybe more idiomatic (but less convenient?) z.deep_set([7, 'A', 'B', 'C', 8, 'mykey'], "Hello World")
  • Return value: z or "Hello World" (z would be more idiomatic)

@rdje https://github.com/rdje, let us know what you think

— Reply to this email directly, view it on GitHub https://github.com/ngs-lang/ngs/issues/549#issuecomment-1032391841, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASSKVHGR54ADPGB3HGG4JZLU2DOUBANCNFSM5NXEW26Q . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

ilyash-b commented 2 years ago

I see why you would want orthogonal (A) description of what to look at and (B) what to do with that (get/set).

There is implementation problem with the suggested above (references). Assignments are of the forms (syntactically):

There is no support for arbitrary expr1 = expr2. I also don't know at this point in time how to do it without performance penalty. Another thing to figure out: implementation of such reference.

Additionally, NGS already has get() and set() methods and the newly suggested method would fit in.

rdje commented 2 years ago

Hi Ilya,

Ok, if you think what I am asking is not doable or without a performance penalty, then fine.

You know what's best.

I was just trying to describe the best way I can how ideally I see the feature being used.

So, if I understand correctly, what you're ok to implement will autovivify using two functions ?

Then, I think I am done harassing you with this autovivification thing ! :-)

Thanks for even taking the time to consider my request.

-Richard

On Tue, 8 Feb 2022 at 17:01, Ilya Sher @.***> wrote:

I see why you would want orthogonal (A) description of what to look at and (B) what to do with that (get/set).

There is implementation problem with the suggested above (references). Assignments are of the forms (syntactically):

  • var_name = expr - implemented as built in
  • expr1.field_name = expr2 - calls .= method
  • expr1[expr2] = expr3 - calls []= method

There is no support for arbitrary expr1 = expr2. I also don't know at this point in time how to do it without performance penalty. Another thing to figure out: implementation of such reference.

Additionally, NGS already has get() and set() methods and the newly suggested method would fit in.

— Reply to this email directly, view it on GitHub https://github.com/ngs-lang/ngs/issues/549#issuecomment-1032770195, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASSKVHERMD2UZD3ZZKRJNKDU2E46BANCNFSM5NXEW26Q . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

rdje commented 2 years ago

Hi Ilya,

I said earlier that I wouldn't bother you again with but I was thinking about what you wrote earlier which I quote below

There is no support for arbitrary expr1 = expr2. I also don't know at this point in time how to do it without performance penalty.

The way I see it is that since you're already able to perform the three types of LHS = RHS you mentioned already, it should be possible to add the more general

expr1 = expr2

You would need to transform it into one of

  1. expr1.fieldname = expr2
  2. expr1[expr2] = expr3

The reason why I am saying this is because the LHS of the above two statements are themselves expressions.

An LHS means a memory location, which means there is a memory address associated with this LHS.

expr1.fieldname or expr1[expr2] act like names to the LHS memory location, so maybe a way to handle

expr1 = expr2

is to automatically create a random name which of course is not accessible to the user, that NGS will use internally to handle this sort of general assignments.

Ok, maybe my idea is just a blatant manifestation of my ignorance of how things are done or can be done in NGS ! :-(

I'll stop here then :)

-Richard

On Tue, 8 Feb 2022 at 18:19, Richard DJE @.***> wrote:

Hi Ilya,

Ok, if you think what I am asking is not doable or without a performance penalty, then fine.

You know what's best.

I was just trying to describe the best way I can how ideally I see the feature being used.

So, if I understand correctly, what you're ok to implement will autovivify using two functions ?

  • deep_set()
  • deep_get()

Then, I think I am done harassing you with this autovivification thing ! :-)

Thanks for even taking the time to consider my request.

-Richard

On Tue, 8 Feb 2022 at 17:01, Ilya Sher @.***> wrote:

I see why you would want orthogonal (A) description of what to look at and (B) what to do with that (get/set).

There is implementation problem with the suggested above (references). Assignments are of the forms (syntactically):

  • var_name = expr - implemented as built in
  • expr1.field_name = expr2 - calls .= method
  • expr1[expr2] = expr3 - calls []= method

There is no support for arbitrary expr1 = expr2. I also don't know at this point in time how to do it without performance penalty. Another thing to figure out: implementation of such reference.

Additionally, NGS already has get() and set() methods and the newly suggested method would fit in.

— Reply to this email directly, view it on GitHub https://github.com/ngs-lang/ngs/issues/549#issuecomment-1032770195, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASSKVHERMD2UZD3ZZKRJNKDU2E46BANCNFSM5NXEW26Q . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

ilyash-b commented 2 years ago

I'm still thinking about refinements. Considering additional methods in the get() and set() multimethods. That would be more consistent with the rest of the language:

An LHS means a memory location

It's better to see at as a value. It can be on stack for example if it's a result of computation. Think a + 2 = 3.

I totally understand having more thoughts with time. I frequently have that too. Feel free.

ilyash-b commented 2 years ago

... except that get(x:Any, path:Arr) collides with get(x:Any, dflt:Any) so need to think more

rdje commented 2 years ago

Ilya,

The issue with your example below

a + 2 = 3

is that, it is a mathematical equality and not a programming language assignment.

A LHS, that is the thing on the left of an equal sign is supposed to be modifiable (mutable) at least once.

a + 2 is not mutable so can't be considered a LHS in a programming sense.

In

expr1 = expr2

The left side of the assignment is supposed to be mutable.

The three cases you're already handling meet the mutability criterion

So a new idea to deal with expr1 in

expr1 = expr2

would be to detect whether or not expr1 is mutable, if it is, then the handling would be similar to the cases you're already handling.

The way I see it is that to implement deep_set() you would need to have access to a mutable object or location. This mutable thing is the target of the route/path provided to deep_set().

The exact same mutable object or expression will be accessible by both deep_get() and deep_set().

For example, the cases you already handle may be rewritten using deep_set() and deep_get(), look

         var_name = expr   ≡  _internal_hash.deep_set("varname", expr)

expr1.field_name = expr2 ≡ expr1.deep_set("fieldname", expr2) expr1[expr2] = expr3 ≡ expr1.deep_set(expr2, expr3)

                var_name  ≡  _internal_hash.deep_get("varname")
    expr1.field_name  ≡  expr1.deep_get("fieldname")
           expr1[expr2]  ≡  expr1.deep_get(expr2)

Which also implies that deep_set() could be rewritten in terms of deep_get().

Finally, the three cases you already handle are in fact the same case that is deep_set(...).

Well things looks straightforward in writing :) but is it really the case in reality, I doubt ! :)

-Richard On Tue, 8 Feb 2022 at 22:09, Ilya Sher @.***> wrote:

I'm still thinking about refinements. Considering additional methods in the get() and set() multimethods. That would be more consistent with the rest of the language:

  • get(x:Any, path:Arr)
  • set(x:Any, path:Arr, val:Any)

An LHS means a memory location

It's better to see at as a value. It can be on stack for example if it's a result of computation. Think a + 2 = 3.

I totally understand having more thoughts with time. I frequently have that too. Feel free.

— Reply to this email directly, view it on GitHub https://github.com/ngs-lang/ngs/issues/549#issuecomment-1033064417, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASSKVHAYAUOP3X2LPZFBZNLU2GBB7ANCNFSM5NXEW26Q . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

ilyash-b commented 2 years ago

a + 2 = 3

I was trying to show assignment to LHS which is not assignable.

would be to detect whether or not expr1 is mutable

Currently have no idea how to do it, especially at parsing time. I wouldn't like to have a function call for each assignment. That's a performance penalty which in current implementation is heavy.

_internal_hash.deep_set("varname", expr)

Nope. There are 3 possible different opcodes which are generated by assignment to a variable: OP_STORE_LOCAL, OP_STORE_UPVAR, and OP_STORE_GLOBAL. None of them is using "varname". They use indexes to avoid the penalty of runtime lookup.

expr1.field_name = expr2 ≡ expr1.deep_set("fieldname", expr2)

While the idea of having one generic implementation is understandable, it's probably not the best tradeoff with performance. If we already syntactically know what we are looking at, we should call the more specific function.

but is it really the case in reality, I doubt ! :)

:)


If you would like, @rdje, I could walk you through the implementation so you could get some feeling in general and about the involved mechanisms specifically.

ilyash-b commented 2 years ago

I was talking about performance but I wouldn't like to project the wrong idea. NGS has very little performance optimizations and is generally pretty slow. I'm just trying not to make it worse. The worst (probably) offender is the naive implementation of a method call: the bottom-to-top scanning algorithm and type checking.

rdje commented 2 years ago

Hi Ilya,

I clearly understand the concern about performance issues and for sure I don't want to make it worse.

All of my comments, remarks are just to try to find a workaround to incorporate the autovivification thing into the current framework without delving into the implementation details (for now).

But hey, I already took too much of your time so I should definitely let you focus on your already long to-do list.

I really need to get used to multimethods and how this impacts code partitioning (modules, packages) and structuring.

In the meantime, I'll try to be quiet about new features as I better understand what's already in, right ? :)

But before I go silent I need to ask one last thing about PCRE Callouts.

I will submit a new GitHub issue for that.

-Richard

On Wed, 9 Feb 2022 at 06:31, Ilya Sher @.***> wrote:

I was talking about performance but I wouldn't like to project the wrong idea. NGS has very little performance optimizations in is generally pretty slow. I'm just trying not to make it worse. The worst (probably) offender is the naive implementation of a method call: the bottom-to-top scanning algorithm and type checking.

— Reply to this email directly, view it on GitHub https://github.com/ngs-lang/ngs/issues/549#issuecomment-1033367695, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASSKVHGO6FZ7RM6MYFFNRCDU2H3Z3ANCNFSM5NXEW26Q . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

ilyash-b commented 2 years ago

Requesting feedback on the early stage experimental implementation - https://gist.github.com/ilyash-b/fd87050fd55e5d0de65a19cbee4b3ceb

ilyash-b commented 2 years ago

Moving discussion to https://github.com/ngs-lang/ngs/discussions/550

ilyash-b commented 2 years ago

@rdje , clarifying the plan. I would like to add something like this to the language only after feedback on real usage (of the prototype we have here).

ilyash-b commented 2 years ago

Closing. Please re-open when real-world usage feedback is available.