Re: import { foo, bar } as obj from 'module

2017-12-12 Thread Tiddo Langerak
Thanks for pointing that out, I didn't know that (I should've tested my 
assumptions). It seems that Webpack does the same.


The entire motivation behind selective namespaced imports relied on that 
assumption, so if treeshaking works with * imports then I don't think 
there's much use for this feature.


On 12/12/2017 09:51 AM, Ltrlg wrote:
2017-12-12 8:39 GMT+01:00 Tiddo Langerak <tiddolange...@gmail.com 
<mailto:tiddolange...@gmail.com>>:


- Star imports prevent treeshaking.


Treeshaking does work with star imports as long as you only have 
statically known usages. At least Rollup handles these situations as 
if it was a named import [1]


[1]: 
https://rollupjs.org/repl?version=0.52.1=JTdCJTIybW9kdWxlcyUyMiUzQSU1QiU3QiUyMm5hbWUlMjIlM0ElMjJtYWluLmpzJTIyJTJDJTIyY29kZSUyMiUzQSUyMmltcG9ydCUyMColMjBhcyUyMG1hdGglMjBmcm9tJTIwJy4lMkZtYXRocy5qcyclM0IlNUNuY29uc29sZS5sb2coJTIwbWF0aC5jdWJlKCUyMDUlMjApJTIwKSUzQiUyMCUyRiUyRiUyMDEyNSUyMiU3RCUyQyU3QiUyMm5hbWUlMjIlM0ElMjJtYXRocy5qcyUyMiUyQyUyMmNvZGUlMjIlM0ElMjJleHBvcnQlMjBmdW5jdGlvbiUyMHNxdWFyZSUyMCglMjB4JTIwKSUyMCU3QiU1Q24lNUN0cmV0dXJuJTIweCUyMColMjB4JTNCJTVDbiU3RCU1Q24lNUNuZXhwb3J0JTIwZnVuY3Rpb24lMjBjdWJlJTIwKCUyMHglMjApJTIwJTdCJTVDbiU1Q3RyZXR1cm4lMjB4JTIwKiUyMHglMjAqJTIweCUzQiU1Q24lN0QlMjIlN0QlNUQlMkMlMjJvcHRpb25zJTIyJTNBJTdCJTIyZm9ybWF0JTIyJTNBJTIyY2pzJTIyJTJDJTIyZ2xvYmFscyUyMiUzQSU3QiU3RCUyQyUyMm5hbWUlMjIlM0ElMjJteUJ1bmRsZSUyMiUyQyUyMmFtZCUyMiUzQSU3QiUyMmlkJTIyJTNBJTIyJTIyJTdEJTdEJTJDJTIyZXhhbXBsZSUyMiUzQW51bGwlN0Q=


Ltrlg



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


import { foo, bar } as obj from 'module

2017-12-11 Thread Tiddo Langerak
In modern ES code, I love the named imports & exports since it allows us 
to only import what we need. Tooling has jumped on this as well by 
stripping out any exports that aren't used (treeshaking).


However, a big downside of named imports is that you lose any 
"namespacing", which is especially relevant for generic 
function/variable names. For example, `lodash` and `async` both export a 
`map` function, and it isn't unlikely to use both packages in a single 
project, or even a single module. This gives naming conflicts.


We currently have 2 options to resolve these conflicts:

- Alias individual imports:

    import { map as lodashMap } from 'lodash';
    import { map as asyncMap } from 'async';

- Replace with * import

    import * as _ from 'lodash';
    import * as async from 'async';

Neither option is ideal:

- Aliasing results in either inconsistent code (some imports are 
prefixed, others aren't) or "smurfnaming". Prefixing is often also less 
readable than namespacing, especially for longer names 
(`lodashLastIndexOf` vs `lodash.lastIndexOf`).

- Star imports prevent treeshaking.

The solution to this seems simple enough: allow a group of named imports 
to be aliased as a whole:


    import { map } as _ from 'lodash';
    _.map();

This preserves both "namespacing" and selective importing, giving the 
best of both worlds.


To me this seems like such a no-brainer that I'm actually surprised that 
this isn't possible already. Has something like this been considered at 
some point? And what would be the downsides of this? Or is there just 
too little interest in this?

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Accesssing ES6 class constructor function

2017-01-05 Thread Tiddo Langerak
I don't think it is possible to call the constructor as a function. 
However, in JavaScript a class is just an object (unlike C# or Java, 
where it's meta data), which means that you can pass it around and 
dynamically extend it. E.g. you can intercept class creation like this:


function enhanceClass(c) {
return class EnhancedClass extends c {
constructor() {
//do your magic here
}
}
}

class MyClass {}

const EnhancedMyClass = enhanceClass(MyClass);
new EnhancedMyClass();

As for `toString` & not being able to call a function directly: 
`toString` is already overwriteable, and in ES5 code it wasn't uncommon 
to throw from a constructor if it wasn't called as one (for good 
reasons). ES6 classes just do that for you.


On 01/05/2017 06:31 PM, James Treworgy wrote:
Hi - I am brand new to this list, I find myself here because of a 
confounding issue related to ES6 classes vs. traditional constructors. 
Forgive me if this is something that's been hashed out in times past. 
I looked around for discussion online and couldn't find anything more 
than the observation that the spec prohibits invoking it - not really 
any discussion. Probably a failing of google more than anything else, 
so if there's some discussion that I should read to catch up please 
point me there.


Here's my issue. The ES6 spec prohibits invoking class constructors 
without "new". This makes such functions a special case, e.g.


class Test() {}

// typeof Test === 'function'  // yep
// Test.prototype.constructor === Test // yep

// Test() => nope ... TypeError: Class constructor Test cannot be 
invoked without 'new'

// Test.call() ... nope
// Test.apply() ... nope

This has some interesting consequences. It means testing something for 
typeof "function" no longer guarantees it can be invoked without 
error. Also "function.toString()" can now return something that isn't 
actually a legal function definiton (since it returns the whole class 
as text). There seems to be no method, through various javascript 
reflection/invocation techniques or otherwise, to invoke a class 
constructor except by creating an instance of the class.


For tool-builders the consequences of this are significant. It's no 
longer possible to create something that can extend/wrap/act on a 
prototype by intercepting it's construction process, as it was before 
with plain ES5 constructors. So classes are fundamentally different 
than prototype contructors in how we can use them, far more than 
syntactic sugar. This has come into play lately for me, as an DI 
container we use that does exactly this doesn't work with ES6 classes 
(and as far as I can tell, there's no way to make it work, other than 
having devs no longer use class syntax).


This seems a strange design decision. Even conventional OO languages 
like C# have the capability to reflect on classes and access the 
constructor directly as a function. It seems to fly in the face of the 
basic openness/dyanamic nature of JavaScript, and more signficantly, 
creates a kind of backward incompatibility since a function is no 
longer just a function.


I'm wondering whether I'm missing some mechanism for legally accessing 
a class constructor as a function (other than parsing the output of 
toString() and eval!) -- and generally thoughts on this aspect of the 
ES6 specification.


Thank you!



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Function constants for Identity and No-op

2016-08-10 Thread Tiddo Langerak
I think this is more about improving readability than saving a few 
characters.


On 08/10/2016 11:10 AM, Isiah Meadows wrote:


I'll note that it's longer than just typing them out manually (and 
close if they're aliased):


```js
Function.IDENTITY
IDENTITY
x => x

Function.NOOP
NOOP
() => {}
```

Not sure if it adds anything.


On Tue, Aug 9, 2016, 14:44 Eli Perelman > wrote:


I'm not sure if something like this has been proposed before, but
I often find myself declaring constants for the identity function
and the no-op function. I think it would be useful to have
constants available on Function containing these values. For
example `Function.IDENTITY` and `Function.NOOP`. Essentially these
constants would map to:

```js
Function.IDENTITY = (a) => a;
Function.NOOP = () => null; // or:
Function.NOOP = () => {};
```

These could then be used in places where non-user-controlled APIs
need default functions need to be executed, or as placeholders for
default values that may be executed before a function has been
supplied. For example:

```js
// third-party API requires a callback or throws, but no
functionality really needs to done:
thirdParty.action(Function.NOOP);

// Function needs a default which *may* execute prior to having a
different one specified (contrived):
const action = (handler = Function.IDENTITY, value = 10)
=>handler(value);
```

Thoughts? Seems like something simple with positive value. Thanks!

Eli Perelman
___
es-discuss mailing list
es-discuss@mozilla.org 
https://mail.mozilla.org/listinfo/es-discuss



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: JavaScript Language feature Idea

2016-04-19 Thread Tiddo Langerak
If we're talking about adding a new method anyway, why not just add a 
more general `get` method with support for both positive and negative 
indices? That would be consistent with the other array methods, and 
additionally I think it is more natural to use `arr.get(-2)` than 
`arr.last(1)`. Using `last` to get anything but the very last element 
just seems weird to me.


On 04/19/2016 10:00 AM, Bruno Jouhier wrote:
Adding `last` to `Array.prototype` is no different than adding 
`endsWith` to `String.prototype`. ES2015 did it.


It won't break most existing code that defines `Array.prototype.last`. 
Such code will just overwrite the new `last` method and will continue 
to work as before.


You won't be able to mix old libraries that have their own `last` 
method with new code if the methods behave differently but that's a 
different story; that's not breaking existing web pages.


What will break though is existing code that test the existence of 
`Array.prototype.last`; but `String.prototype.endsWith` had the same 
issue.


last(1) would return last but one, and last() would be the same as last(0)


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss