Release 0.23.0

Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Release 0.23.0

Herby Vojčík
Hello all!

================
   ANNOUNCEMENT
================

Big new release is out!

In the version 0.23.0, lots of inner changes were made. But, most of
them have backwards compatibility, so your old code should load.

TL;DR:

   npm -g install @ambers/cli

and your new projects will be created with new version.
For cases where npm think it knows better,

   npm -g uninstall @ambers/cli -f
   npm cache clean -f
   npm -g install @ambers/cli -f


===================
   THE CHANGES
===================

 From CHANGELOG:

* Remove kernel-level deprecations.
* `imports:` loaded lazily using isReady promise
   * you can have circular `import:` clauses
   * you cannot presume your `import:` dependency is initialized in your
own class-level `initialize`
* `aJsObject Uppercase: foo and: bar` is called as
`aJsObject.Uppercase(foo, bar)`
   * only the unary `aJsObject Uppercase` is special and returns
`aJsObject.Uppercase`
   * so far all uppercase selectors made an exception, even ones with args
* `aJsObject selector: foo withMoreArguments: bar` fails if
`aJsObject.selector` is not a function
   * only the single-arg `aJsObject selector: foo` sets the value
`aJsObject selector = foo`
   * so far even more-than-one-arg ones did set the value denoted by
first keyword
* Namespace change: amber_core => amber/core.
   * Backward compatibility mapping added, so old code should load and
save with new implicit deps.
   * You must edit explicit deps (aka `imports:`) as well as Gruntfile,
deploy, testing and devel .js files yourself.
* Instance variables are now compiled as `obj.ivarName` instead of
`obj["@ivarName"]`.
   * There is compat layer so old code is loadable.
* Classes can be created using API containing `slots: {#foo. #bar}`
instead of `instanceVariableNames: 'foo bar'`
   * Smalltalk files are saved using this new API.
   * No actual slots yet, only 'plain data slots' eg. instance variables.

--- imports: are lazy ---

When you put a dependency to imports:, it is now loaded lazily. This is
possible because you need your `imports:` for your code to run, but they
are not needed for your code to load. So load dependencies only contain
those items which Amber can derive automatically (location of
superclasses, used traits and classes then the package adds extenstion
methods to). The rest is not needed until the code is actually run.

The first consequence is, you can have circular dependencies in
`imports:`. The `imports:` was mainly created to be able to load
external JS lib for use in Amber; but you can add amber package module
id there as well -- thereby telling Amber you need that package for your
code to work. As package can refer to foreign classes freely, there can
be circular run-dependencies; but those are ok now, as `imports:` are no
longer a strict load dependencies, thus loading of your project won't fail.

The second consequence is; you don't know what order your
class-side#initialize will be called (except superclass is initialized
before subclass). So even if you run-depend on some other package, in
your class-side `initialize` do not presume it is itself class-side
`initialized` (you shouldn't, anyway; just saying explicitly).

--- JS proxy message send translation cleared ---

A few, IMHO common sense, changes were made to the process of how
`aJSObject message: foo and: bar` is translated to actual JS calls /
property read / property write.

This summarizes it:

| selector      | condition            | action        | fixed from   |
|===============|======================|===============|==============|
| foo           | obj.foo not present  | DNU           |              |
| foo           | obj.foo is function  | obj.foo()     |              |
| foo           | obj.foo not function | obj.foo       |              |
| Foo           | obj.Foo not present  | DNU           |              |
| Foo           | obj.Foo present      | obj.Foo       |              |
| foo: 4        | obj.foo not present  | DNU           |              |
| foo: 4        | obj.foo is function  | obj.foo(4)    |              |
| foo: 4        | obj.foo not function | obj.foo = 4   |              |
| Foo: 4        | obj.Foo not present  | DNU           |              |
| Foo: 4        | obj.Foo is function  | obj.Foo(4)    | obj.Foo = 4  |
| Foo: 4        | obj.Foo not function | obj.Foo = 4   |              |
| foo: 4 bar: 5 | obj.foo not present  | DNU           |              |
| foo: 4 bar: 5 | obj.foo is function  | obj.foo(4, 5) |              |
| foo: 4 bar: 5 | obj.foo not function | Error         | obj.foo = 4  |
| Foo: 4 bar: 5 | obj.Foo not present  | DNU           |              |
| Foo: 4 bar: 5 | obj.Foo is function  | obj.Foo(4, 5) | obj.Foo = 4  |
| Foo: 4 bar: 5 | obj.Foo not function | Error         | obj.Foo = 4  |

--- core namespace change ---

Amber core libraries had ugly path prefix amber_core. Now they are all
at amber/core. You code should load fine, and save with new prefixes in
implicit dependencies.

In case you added some 'amber_core/Foo' into `imports:`, you must edit
it yourself (it will load, though, for a time).

--- instance variables implementation ---

Instance variable are not implemented by accessing a JS property equal
to their name, not mangled any more. So they are compiled to $self.ivar,
not $self["@ivar"] any more.

This has two consequences: first, in some cases you should be careful
with names (hasOwnProperty, valueOf), especially when you capture
existing JS class using javascriptConstructor:.

OTOH, this allows you to much easier write code for such captured
classes, as you simply use ivar to access its properties. Lots of

prop
   <inlineJS: 'return $self.prop'>

can be gone in favour of simple

prop
   ^ prop

Of course, old code using ["@ivar"] is loadable as there are fowarding
getters and setters set up (for some time :-) ).

--- slots: in class creation API ---

Class creation API (subclass:uses:instanceVariableNames: .... in
instance side; as well as uses:instanceVariableNames: ... in class side)
has now a variant with 'slots:' instead of 'instanceVariableNames:', the
'slots:' version accepting the array of symbols, not a space-separated
string.

This new API is also canonical, so every exported .st files uses these.
The old ones are kept around for compatibility and forward to the new ones.

So far no real slots are in Amber - but as JS allows its properties to
have different forms (non-enumerable, non-writable, getter/setter pair),
it is envisioned some support for slots to be able to make these things
happen will arrive; as well as adding slots (either in actual "just
another ivars" form or in richer aforementioned one) to traits as well.

================
   BOTTOM LINE
================

Please migrate your projects.

The mechanical, though needing a bit of tools experise, but working, way
to do it is to create new project with `amber init` with the same name
as the old project, copy the files over to old project, and go over the
diffs (shown by git / IDE / both) manually.

Herby

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.