Giter Club home page Giter Club logo

haxe-evolution's Introduction

Haxe change proposals

This project is for maintaining formal change proposals for Haxe language.

List of accepted proposals

# Name Author Status
0001 Any type Dan Korostelev implemented in 3.3.0
0002 Arrow functions Alexander Kuzmenko implemented in 4.0.0
0003 New function type syntax Dan Korostelev implemented in 4.0.0
0004 Intersection types Simn implemented in 4.0.0
0005 key => value iteration syntax Dan Korostelev implemented in 4.0.0
0006 Inline markup Juraj Kirchheim implemented in 4.0.0
0007 Module-level functions and variables Dan Korostelev implemented in Haxe 4.2.0
0008 Expression macro method forwarding Dan Korostelev to be implemented
0009 Inlining functions at call location YellowAfterlife implemented in 4.0.0
0010 New asys APIs Aurel Bílý to be implemented
0011 Local bariable metadata syntax Peter Achberger implemented in 4.2.0
0012 Abstract classes Aleksandr Kuzmenko implemented in 4.2.0
0013 Default type parameters Ben Merckx implemented in 4.3.0
0014 Self access for abstracts Mark Knol implemented in 4.3.0
0015 Local static variables YellowAfterlife implemented in 4.3.0
0016 Null coalescing operator RblSb implemented in 4.3.0
0017 Null-safe navigation operator Robert Borghese implemented in 4.3.0
0018 Number separators Marcelo Silva Nascimento Mancini implemented in 4.3.0
0019 Numeric literal suffixes Aidan Lee implemented in 4.3.0

About proposals

Haxe Proposals (HXP) can be submitted by any Haxe team developer or community member, as long as it's complete and well explained (please see the "How to submit an HXP" section below).

Once a HXP has been submitted, it can be discussed and modified. Anybody can also submit a PR against an existing HXP to have it amended.

Please understand that the HXP discussion and voting process is for cases where the core team is not opposed to the proposed changes. The team internally discusses all proposals; if they are opposed to a given HXP then it may be rejected with very little public discussion in the PR comments. There is simply not enough time for the core team to provide detailed written rationale for every proposed change which they think would not be a good overall fit for Haxe.

After the HXP has been discussed, a formal vote can take place to accept it. Only Haxe Core Team members are allowed to vote:

To be accepted the HXP needs half + 1 votes in favor of it.

In order to keep the long term goals and vision of Haxe, Nicolas can veto any accepted proposal after the vote, but will explain his reasoning for doing so in details and agrees to use this power with care.

If the HXP is accepted, the core team will work on implementing it.

What needs a proposal?

Stuff that doesn't need a formal proposal (unless it's something fundamental):

  • bugfixes
  • optimizations
  • documentation
  • minor API additions

Stuff that most probably needs a formal proposal:

  • language changes, including adding new features
  • breaking standard library changes
  • large standard library additions (new toplevel types are also considered "large")
  • significant compiler architecture or build process changes

Basically, everything that needs some design process and consensus among the developers is a candidate for a proposal.

How to submit an HXP

  1. Fork the repo, copy the 0000-template.md to proposals/0000-short-name.md, where short-name is a descriptive filename for the proposal document. Don't assign the number yet.
  2. Carefully fill in all sections of the proposal. Pay attention to details: it should show your understanding of the issue and the impact of the proposed design.
  3. Submit a pull request with the proposal. In this PR, Haxe team and the community can provide feedback for it. Be prepared to react accordingly and revise the proposal document.
  4. After reaching general consensus or voting takes place, the PR is merged by someone from the Haxe developer team, and the proposal becomes "active". When merged, the proposal will receive its number from the corresponding pull request. If the proposal is rejected, the PR is closed with a comment explaining the reasons.
  5. Active proposals are to be further discussed in details by the Haxe developer team and finally implemented.

Voting process

It's the responsibility of the author of a proposal to start the voting process.

Once discussion is exhausted, the author of a proposal can request the voting. Following requirements should be met:

  • All questions asked by the core members of Haxe Foundation to the author are answered;
  • The last edit to a proposal was made at least two weeks ago;
  • The last message in the discussion was posted at least two weeks ago.

To start the voting process the author should post the comment:

Request for voting.

Additionally, the author can tag voters in this comment to draw their attention (example).

After this comment is posted the discussion will be locked by any Haxe Foundation member with write access to the haxe-evolution repository. From that point only voters will be able to post comments to the discussion.

haxe-evolution's People

Contributors

aidan63 avatar andyli avatar antriel avatar aurel300 avatar back2dos avatar benmerckx avatar codingthat avatar gama11 avatar markknol avatar mrcsnm avatar nadako avatar ncannasse avatar rblsb avatar realyuniquename avatar simn avatar somerandev avatar uvtc avatar yellowafterlife avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

haxe-evolution's Issues

[PROPOSAL] Making package statement optional

The package statement at the top of the file has always felt superfluous to me. The compiler already knows the package the file should have from the directory path it walked to find it.

I propose that when the package statement is missing the haxe compiler will automatically assign a package generated from the module's file path.

I'd like to know the general sentiment on this, I'll write formal proposal PR if it makes sense.

Add status information to active proposals?

I think it would be very useful to see on active proposals their status. E.g., what version of Haxe they were implemented in (if implemented) or what milestone they are expected to make (if not yet completed). E.g., I am interested in seeing HXP-0001 exist. If I read the entire detailed contents I can see that there are hints that it might be available by Haxe-4. But it’s not very clear and requires digging.

I think showing the status on all proposals would become more useful in the future when at least one proposal is actually implemented so you can quickly check if you can use it yet.

EcmaScript 4 syntax

Haxe has some subtle differences from TypeScript and EcmaScript 4 (inexistent) syntax.

  • For aliasing types, TypeScript choose to use the context keyword type rather than a reserved word typedef. EcmaScript 4 too was going to use type (whether in ES4 it was going to be contextual or not I don't remember, though the EcmaScript 4 reference interpreter is available in archive.org).
  • In TypeScript, you can express Array<T> as T[]. In EcmaScript 4 you would be able to express Array.<T> as [T]. To me, it seems like the EcmaScript 4 syntax for specifying array types in brackets is cryptic and readable at the same time.
    • Both TypeScript and EcmaScript 4 express tuple types with the same syntax, consisting of two or more element types.
  • In TypeScript, the dynamic type is written any. In EcmaScript 4, it's written *.

More specifically, in these languages, type is reserved when it's followed or preceded by another identifier or reserved word, so it doesn't break compatibility.

Here's a Haxe version:

var a:Array<Dynamic> = [];

typedef DoublePrecisionFloatingPoint = Float;

Here's an EcmaScript 4 version:

var a:[*] = [];

type DoublePrecisionFloatingPoint = Number;

I think it'd be interesting if Haxe supported the same ES4 syntax for clarity, considering it'd not break compatibility. It doesn't break macros, does it? After all, Haxe was inspired by ES4.

Another thing I didn't mention is that the decorator syntax of ES4 used brackets, not @:.

implements for abstracts? Why not?

Hi i think about a feature that haxe not support yet.

abstract NewClass (OldClass) implements AnInterface {
    public function test() {
        this.test();
    }
} 

Currently i do it like this:

class NewClass implements AnInterface {
     private var clazz:OldClass;

     public function test() {
         clazz.test();
     }
}

What you think about it?
From: (HaxeFoundation/haxe#6678)

Example:

class A {
    public function new() {}
    public function test() {}
}

interface ITestDebug {
    public function testDebug():Void;
}

abstract B (A) implements ITestDebug {
    public function new() {
        this = new A();
    }
    public function testDebug() {
        this.test();
    }
}

class Main {
    public static function main() {
        var b:B = new B();

        // b.test(); <- should not work because is it not visible anymore

        testDebugCall(b);
    }

    public static function testDebugCall(testDebug:ITestDebug) {
        testDebug.testDebug();
    }
}

And it can be compiled like an extends (but only for compile time):

class B extends A implements ITestDebug {

[stage2] Haxelib replacement

Foreword

Issues in this repositories tend to get bogged down in long-winded discussions without much of a result. We would like to try a slightly different approach which is outlined here: https://github.com/HaxeFoundation/haxe-evolution/wiki/Haxe-Projects

We are in Stage 2 here, which means that discussion should be limited to the items from stage 1. Below is the result of stage 1, ordered descending by rating (= Upvotes - Downvotes - Off topic votes). I am only listing items which had more than 5 rating. This doesn't mean that all other aspects should be completely ignored (especially late entries which might not have had enough time to get votes), but the focus should still be on the list below.

Now on to the actual project.


Haxelib replacement

Project lead: Simn
Stage 1 issue: #30
Due date for stage 2: 2017-11-6 (3 weeks)

We are looking to replace haxelib with a better package manager solution.

Feature set

  • (17)
    • semver dependency management, and solution to handle conflicts as we can have only one version of a lib,
    • global cache and local libs similarly to npm/yarn,
    • support for git / file dependencies.
  • (16) The Haxe compiler should not have to call a separate tool to obtain the information required for compilation.
  • (16) The package manager should use secure protocols (HTTPS vs. HTTP) for downloading packages (I found this to place limitations on the choice of a suitable runtime).
  • (15) Support lock files so we have reproductive build system
  • (15) If I install a new dependency, upgrade a dependency, or change my dependencies in any way, this should show up in a way that is tracked in a file in my version control, and can be used to restore the same state on a different computer.
  • (12) Don't have to deprecate it, but it shouldn't require a run.n. It could, by convention, make haxe interpret a Run.hx script instead.
  • (12) haxelib.json should be extended, proposed new fields (non exhaustive):
    • repository field (to go with the current website field)
    • listing the metas/defines of the library
    • haxe version compatibility
  • (11) It should be possible to open a directory that a project is in, and when I type haxe build.hxml it automatically uses the configured version of Haxe for the project, and the right set of haxelibs/dependencies.
  • (10) From Haxe code it should still be possible to know which libs are used. so doing #if (libname > 4). It would also be useful to be able to know which classes come which library (in macros/ documentation xmls/dependency dumps etc)
  • (8) The compiler should expose an interface for frontends like CLIs, IDEs, vscode-style language servers, and so on.

General guidelines (higher level)

  • (15) The user should be able to use an alternative package manager (without making change to or replacing the haxe exe).
  • (13) Configuration must be thoroughly documented and transparent. On-disk storage such as hidden .dev, and .current files should be discouraged and instead replaced by a documented configuration file.
    The final goal is to make it so that alternative library managers can use/manipulate the same library database without having to know the details of the previous manager.
  • (10) The standard mechanism to invoke the compiler will be a first point of contact for newcomers to the language. As such it should provide an outstanding user experience and documentation can't be an afterthought.
  • (8) A migration plan is required:
    • what happens to the already installed libraries? do they need to be reinstalled?
    • do we keep the haxelib online repository as is? if not what about usernames?

Additional syntax for safe navigation

I wanted to make a new home for a topic of discussion that is somewhat dispersed right now.

Safe navigation was implemented for object field access in 4.3.0, however it was not implemented for array access or function calls, despite being included in the original proposal #89 .

Array Access

The original proposal dictated that accessing nullArray?.[0] would return null, as opposed to nullArray[0] which currently throws a TypeError.

This syntax is notably useful in cases where you are working with nested arrays, like nullArray?.[i]?.[j]?.[k]. The fallback behavior is also very clear.

The syntax of ?.[] is used over ?[] since the latter is indistinguishable from a ternary operator by the parser. This syntax would notably be shared with Javascript and no other language.

Function Calls

The original proposal dictated that accessing nullFunction?.() would return null, as opposed to nullFunction() which currently throws a TypeError.

This syntax is notably useful primarily in the case where you are performing multiple object chaining operations in one line, such as object1?.object2?.myFunction?.(). It also may be used in the case where you use an optional callback function.

The main reasoning behind these not being implemented with the original proposal, as stated here: https://www.youtube.com/watch?v=lkpoTcHKjSE&t=454s

We didn't add the other variants, you sometimes see ?[ or ?( to make calls. We weren't sure if this was really needed, to me it looks kind of... it looks a bit awkward, and there might be use cases for it, but for now we decided to just stick to this one.

Additional possibilities!

Is it possible to create Nested class declaration 1.
Multiple extending class unlimited 2.
Nested typedefinitions, nested structures and all statement items nestedable.

Syntax sugar changing 3. Multiple implementation / inheritance.
Anonymous class declarations 4.
Python like syntax to change between tab indent and inbrackets blocks. 5.

class PreClass1
 public function new () {}

class PreClass2
 public function new() {}

class Test1 extends PreClass1, PreClass2 implements ITest1

 // add the class root object as additional type!.
 anonymousclass = class
   public inline function testInline() {return True;}

  public function new()
  {
    super.class._1(); // index firstly defined in extends row class supercall.
    super.class._2(); // or class.PreClass1() or super.PreClass1()
  }

Standardized build config

Moved from #42

I agree with the goal but we're bumping up against the limits of what a format like hxml should reasonably support (hierarchical structure?) There's a natural split between compiler args and build configuration: build config should be flexible and expressive, and generates a set of compiler args for a single build, which can be simple and specific. So an alternate approach would be to standardize what build configuration looks like across projects, rather than overloading hxml.

So my alternative suggestion is to standardize a subset of OpenFL's project.xml/include.xml functionality, because that project has already solved this problem in an elegant way. (Syntax and format are less important than functionality here, pick your favorite markup language. I'll use YAML for this example because it's concise.)

There has also been a suggestion to add more metadata fields to haxelib.json, and include.xml solves that problem as well. If haxelib.yaml (or whatever) is present, it takes precedence over haxelib.json, and otherwise can include the same information. And while we're at it this also eliminates the need for extraParams.hxml.

name: hxpk
version: "0.1.0"
license: "MIT"
contributors: ["bendmorris"]

src: ["src"]

flags:
- "-dce=full"

dependencies:
- format
- hxbit

section:
- if: test
  unless: no-test
  flags: ["-debug"]
  dependencies: ["unit"]
  src: ["src-tests"]

This generates a set of compiler args: haxe -cp src -dce=full -lib format -lib hxbit. If called with -Dtest, it adds extra args: -debug -lib unit -cp src-tests.

There might be pushback that "haxe/haxelib is not a build tool." True, but having so much fragmentation among build tools is not great and Haxe doesn't have a clear winner in that space. At minimum we should have a standard format and set of semantics that works for basic projects and is expressive/extensible enough for build tools to consume without needing to provide their own entirely separate format.

[Open Discussion] Cast Specification

ATM in Haxe 4 we have different ways to cast a type to another:

  • the "safe cast", which is cast(expr,T)
    • at compilation : will ensure that the type of expr is a subtype of T so the cast is valid
    • at runtime : will perform the typecheck and throw if not satisified
  • the "safe downcast", which is Std.downcast(expr,T)
    • very similar to the safe cast, but returns null instead of throwing an error if the cast is not satisfied.
    • can be used instead of a expr is T combined with a cast(expr,T)
  • the "unsafe cast", which is var v : T = cast expr
    • no compile time check is performed
    • runtime check is only performed on static targets, which will throw an exception on these targets only. On JS for example no error will occur
    • sadly that's at the same time the most unsafe AND the shortest to write.
  • additionally we have expr is T and Std.isOfType(v,T) to check if an expression is of a given type at runtime, the Std.isOfType allowing to specify the type as a variable.

I know it's a bit late but I think we should change this for Haxe 5, as this is the kind of big change we except and allow in a major release.
My proposal would be to:

  • make the current unsafe cast syntax do the same thing as the safe cast, so var v : T = cast expr would be the same as var v = cast(expr,T).
  • introduce a Std.unsafeCast(expr) that would replace the unsafe cast, but then be much more explicit.
  • promote downcast to a keyword and allow both var v : T = downcast expr and var v = downcast(expr,T) the same as the safe cast but with a null result.

[PROPOSAL] Optional chaining operator

The optional chaining operator (?.) would access a property or call a function of an object in a similar manner to ..

However, unlike ., if the object whose property is accessed is null, or the function being called is null, null will be returned instead of throwing a Null Object Reference or Null Function Reference

Examples:

var a = { b: "Test" };
var c = null;

return a.b; // returns "Test"
return c.b; // throws an exception if c is null

return c?.b; // returns null if c or c.b is null

// Equivalent to 'return c?.b;'
if (c == null) return null;
return c.b;

Optional chaining operators can be nested:

return a?.b?.c?.d?.e?.f?.g; // returns null

// Equivalent code is long!
if (a == null) return null;
if (a.b == null) return null;
if (a.b.c == null) return null;
if (a.b.c.d == null) return null;
if (a.b.c.d.e == null) return null;
if (a.b.c.d.e.f == null) return null;
return a.b.c.d.e.f.g;

Optional chaining operators should also be used for function calls:

return a.b.callFunction(); // throws an exception if a or b is null.

return a?.b?.callFunction(); // returns null.

Optional chaining can also be used to validate function calls:

var onCompleteCb:Int->Void;

function onComplete(result:Int) {
    // If onCompleteCb is not null, it will be called.
    // If onCompleteCb is null, does nothing (returns null) rather than throwing an exception
    onCompleteCb?.(result);
}

Specifics

For specifics on niche cases and implementation, refer to how optional chaining is implemented in JavaScript.

Are syntax suggestions acceptable?

Just to know, whether syntax suggestions are acceptable here?
Haxe is pretty verbose, and could use some convenience syntax, in my opinion.

@:optional replacement and initStruct problem?

would like to float the idea of
@:optional var space = 0.;
is replaced with
var space ?= 0.;

My contexct is I am slightly confused on @:initStruct can I still have a constructor afterwards? For example I was wanting to use initStruct to clarify construction with:

class Label extends Actor {
    public var content:  String;
    public var font:     Font;
    public var color:    Color;
    public var size:     Int;
    public var spacing:  Float;
    public var image:    Image;
    public var useImage: Bool;
    public function new(    content_:       String
                        ,   font_:          Font
                        ,   color_:         Color
                        ,   size_:          Int
                        ,   ?spacing_:      Float = -1.
                        ,   ?x_:            Float = 0.,     ?y_: Float = 0.
                        ,   ?useImage_:      Bool = true ){
        content     = content_;
        font        = font_;
        color       = color_;
        size        = size_;
        spacing     = spacing_;
        useImage    = useImage_;
        var width_: Float;
        if( spacing == null ){
             width_ = font.width( size, content );
        } else {
            var dW = 0.;
            for( i in 0...content.length ) {
                dW += font.width( size, content.substr( i, 1 ) );
                dW += spacing;
            }
            width_ = dW - spacing;
        }
        var height_ = font.height( size );
        super( width_, height_, x_, y_ );
        if( useImage ) generateImage();
    }
//... more methods

But I am unsure, is there an example use case of also calling new? Also I am unsure if I can indicate some how that some private parameters in this class or the super should be set later not at construction the current situation is that you could set any private property at construction which could be very problematic, how can the user know what they are allowed/suggested to setable?

Allow inline XML

In the old days of AS3 one can write XML directly in code:

var xml:XML =
    <myXML>
        <valueOfMyVar>???</valueOfMyVar>
    </myXML>

Is there a reason Haxe doesn't support that? If there aren't any I would like to add a proposal for that.

[RFC] Block strings

As part of our syntax changes in Haxe 4.0, we wanted something allowing users to embed any kind of DSL within Haxe syntax. That could be JSX, HTML, or anything else not necessary XML based.

In order to do that we need two new syntactic elements (tags). One tag for opening a block string and one tag for closing it.

Some languages uses triple quotes as tags, such as:

"""
anything that can contain newlines
and
also " quotes and ' as well
"""

But since such strings can be processed with macros, we want them to be reentrant (so they can contain haxe code which itself contain block strings), so we need to distinguish opening tag from closing tag, in order to detect end of parsing, such as the following example shows:

#OPEN
anything that can contain newlines
and
also ${ if( flag ) #OPEN can be reentrant #CLOSE }
#CLOSE

In that example, we use #OPEN/#CLOSE as block strings delimiters, and we make sure that when we enter the first #OPEN, we will detect #OPEN/#CLOSE inside it until the last #CLOSE.

Since several of the DSLs that we wanted to embed in Haxe 4 were XML based, we choose to have <node-name as opening tag and </node-name> as closing tag.

This works pretty well as the following example shows:

var myQuotedString = <code>
anything that can contain newlines
and
" quotes ' 
and doesn't have to be <strict xml at all actually
</code>

This work well with reentrency too:

var myQuotedString = <code $specific>${ if( flag ) <div>something</div> }</code>

However we found a problem with self-closing xml nodes, for two reasons:

  • the first reason is that var x = <code something/> is not valid under the strict definition of opening and closing tags, and we can't make /> a closing tag as well without validating the whole xml, which we definitely don't want to do as this would restrict the allowed syntax inside block strings
  • the second reason is that the following does not work either var x = <div><div/></div> because since our opening tag is <div , it detects two opening tags but only a closing one.

So far we have patched this doing the following rule: when we find <div , we look until we either find < or > , in which case the block is opened, or until we find /> which means it's a self closing tag.

IMHO this is not a good solution as this makes some assumptions about the content and syntax of the block string, which we should avoid (apart from opening/closing tags definition).

As the feature is still experimental, we need to either accept it the way it's done, or find better opening/closing tags. Candidates are ones that would not conflict with existing syntax, and allow for nice reentrency.

For example, while [[[...]]] are not that bad, reentrency looks very ugly, especially when you want to embed some actual XML/JSX/etc. :

var myQuotedString = [[[<code $specific>${ if( flag ) [[[<div>something</div>]]] }</code>]]]

My proposal would be use ~<node-name and </node-name>~ as this does not impact much readability but still allows for correct detection of such tags:

var myQuotedString = ~<code $specific>${ if( flag ) ~<div>something</div>~ }</code>~

Please note that we could also add />~ as a closing tag, so self-closing nodes works as well.

Of course, any other proposal is welcome before we change this.

Three possible choices for final design:

  • keep <node and </node> as tags, forbid usage of self-closing (only of the "top level" node), work on error detection to give good error messages
  • keep current behavior : <node and </node> but makes some very arbitrary assumption that the inner syntax is XML based (potential issue example: <code>if( x<code.length ) echo $T</code> here <code is wrongly interpreted as an opening node)
  • find an alternate syntax for tags such as ~<node ... </node>~

Allow (some) keywords as field names / var names

Since field access is pretty much predictable, I think it should be ok.

The main problem lies in import MyClass.* where the field access becomes unpredictable (and this becomes the same case as var names). So keywords that can act as the beginning of an expression, such as var, function, controls keywords (e.g. if, switch, while...), should still be forbidden.

So I think some of the possible candidates are:

obj.default();
obj.enum;
obj.in();
obj.macro();

etc...

[stage1] Haxelib replacement

Foreword

Issues in this repositories tend to get bogged down in long-winded discussions without much of a result. We would like to try a slightly different approach which is outlined here: https://github.com/HaxeFoundation/haxe-evolution/wiki/Haxe-Projects

We are in Stage 1 here, which means that comments should be short and to the point as mentioned in the document. If you want to discuss the procedure, please open a separate issue.

Now on to the actual project.


Haxelib replacement

Project lead: Simn
Due date for stage 1: 2017-10-14 (2 weeks)

We are looking to replace haxelib with a better package manager solution.

Please share your ideas and concerns in a concise manner. Please also +1/-1 individual comments that you agree/disagree with.

Quote delimited #if statements

Some libraries have non-identifier tokens, which can't be used in identifiers for #if statements, mostly "-". To make from and to functions for abstracts, it would be useful to help interop.

Emoji reaction

While +1/-1 means agree/disagree obviously, I would like to express "this is irrelevant/off-topic" as well. How about using the "confused" emoji ?

[PROPOSAL] Iterator Improvements (Step, Reverse, Float)

I'd like to see more functionality for iterators, inspired by Ruby.

// Standard IntIterator
for (i in (0...10))
  trace(i); // 1, 2, 3, 4, 5...

// PROPOSALS

// Reverse Iterator
for (i in (10...0))
  trace(i); // 10, 9, 8, 7, 6

// Step Iterator
for (i in (0...10).step(2))
  trace(i); // 0, 2, 4, 6, 8

// FloatIterator with Step
// Compiler type-checks min and max to determine if it is an Int or a Float before choosing an iterator.
for (i in (5.0...7.5).step(0.1))
  trace(i); // 5.0, 5.1, 5.2, 5.3, 5.4, ...

I was actually able to implement step(value:Int):IntIterator locally without modifying compilation, but reverse and FloatIterator would require compiler changes (I got a "Cannot iterate backwards" error)

This is pre-draft, but if nobody has any obvious problems with it I will write up a more formal proposal

Support default arguments for enum constructors.

I think this issue is pretty well summarized by the following code snippets.

/**
 * The syntax below has intuitive behavior, but is not supported Haxe syntax.
 */
enum TestEnum {
	INTEGER(value:Int = 0);
}

class Test {
  static function main() {  
    var value:TestEnum = INTEGER();
    // NOTE: It'd be nice to also be able to do this as long as all arguments are nullable or have defaults.
    var value2:TestEnum = INTEGER;
    
    switch(value) {
        case INTEGER(innerValue):
            trace('Inner value was: $innerValue');
    }
  }
}
/**
 * The syntax below is valid syntax but requires handling default values where they are processed.
 */
enum TestEnum {
	INTEGER(?value:Int);
}

class Test {
  static function main() {  
    var value:TestEnum = INTEGER();
    
    switch(value) {
        case INTEGER(innerValue):
            if (innerValue == null) {
                innerValue = 0;
    	    }
            trace('Inner value was: $innerValue');
    }
  }
}

In my opinion, the improvement in code quality is substantial, the new behavior is obvious, and there are no issues with backwards compatibility since the syntax is not previously valid.

I'll open this issue up as a place for feedback and comments before writing up a proper evolution proposal.

iphone and android travis-ci ?

Struggling to get NME's iosview to work even reading issues and trying to rebuild stuff.
HaxeFoundation/hxcpp@7707d6b
HaxeFoundation/hxcpp#504

I often consider Haxe's mobile abilities are the "Rails" feature of haxe so it's vital that they become more and more robust, think a setup with NME and hxcpp would be enough, perhaps this would provide nightly hxcpp's to go with Haxe ones or is that already?

Please can we get Android and Iphone builds on Travis-CI . Found something on iphone travis-ci here:
https://www.objc.io/issues/6-build-tools/travis-ci/

Sorry I have not created a pull request I was not sure of the right format and where I work are kind of funny about me creating opensource repositories ( they want me to send them every commit !!) so this seemed simpler.

Default value for enum parameters

I was surprised to find that while

enum Schedule {
    Hourly(?minute:Int);
    // ...
}

is possible, this is not:

enum Schedule {
    Hourly(minute:Int=1); // characters 18-19 : Unexpected =
    // ...
}

Right now I have to do additional null-checks on enums with optional parameters like so

var instance = new MyClass(Schedule.Hourly());

function MyClass {
    var schedule:Schedule;

    public function new(var schedule:Schedule){
       // validate schedule
       switch (schedule) {
           case Hourly(minute):
                // check for null and apply a default value if found
                if(minute == null) {
                   minute = 1;
                   schedule = Schedule.Hourly(minute); 
                } else if (minute < 0 || minute > 59)  
                   throw "Hourly.Minute must be >= 0 and < 60";
                }
            // ...
       }
       this.schedule = schedule;
    }
}

instead of simply:

var instance = new MyClass(Schedule.Hourly());

function MyClass {
    var schedule:Schedule;

    public function new(var schedule:Schedule) {
       // validate schedule
       switch (schedule) {
           case Hourly(minute):
                if (minute < 0 || minute > 59)  
                    throw "Hourly.Minute must be >= 0 and < 60";
            // ...
       }
       this.schedule = schedule;
    }
}

Therefore I would request adding default value behaviour for enums as specified here https://haxe.org/manual/types-function-default-values.html

[RFC] XML DSLs

Followup regarding my previous RFC #57

First, thank you for all the comments, after reading the whole discussion and taking time to think about it, I would like to update my proposal.

I agree it is hard to have both the goal of "Universal" block strings and still support XML syntax correctly. Some also mentioned that one of the interesting parts about the feature were some kind of IDE support for syntax highlight and autocomplete, so having the feature too abstract would prevent this.

I still think that some kind of XML DSL syntactic support is - if not absolutely needed - at least interesting enough to have in Haxe. HTML is here to stay for a long time and the XML document model that comes with it can be used for many different other applications as well outside of web client code.

I also think we should not support a single particular DSL such as JSX which spec can evolve and change in unexpected ways, or be entirely deprecated by another alternative syntax - whatever the trending framework happens to be in JS world.

So here's a revised syntax proposal that is trying to ensure that most XML based DSLs will be supported, while still trying to make the strict minimal assumptions about the DSL syntax.

An XML DSL node would be in the form:

<nodename CODE?>

Where CODE (optional) is explained below.

We would then try match with the corresponding closing XML DSL node in the form:

</nodename CODE?>

And we would allow self-closing nodes in the form:

<nodename CODE?/>

CODE section can be anything, expect the > character.

But this creates some invalid syntaxes, for instance the following, because of the comparison inside CODE section:

var x = <node value="${if( a < b ) 0 else 1 }"/>

So I propose that CODE additionally check for opening/closing curly braces {} and ignore their whole content. So for instance the following would be perfectly valid:

var x = <yaml {
   some yaml code with balanced {}
} />;

We could additionally treat \{ as escape sequence for the following case:

var x = <node value="\{"/>

I think this version of the syntax gives enough flexibility with minimal assumptions. Using curly braces is done in order to ensure that reentrency is fully supported so any Haxe code within the DSL will be correctly handled.

constrained properties can be typed if you cheat.

I wrongly assumed that because properties are icing that I could constrain them.

typedef Tpoint = {
  var x:Float;
  var y:Float;
}
class Cpoint {
    public var x: Float;
    public var y: Float;
    public function new( x_: Float = 0, y_: Float = 0 ){
        x = x_;
        y = y_;
    }
}
@:forward
abstract Apoint<T:Tpoint>( T ) to T from T {
    public inline
    function new(  p: T ){
        this = p;
    }
  	public var prop<S:Tpoint>( get, set ):Apoint<S>;
    public inline
    function set_prop<S:Tpoint>( a:Apoint<S> ):Apoint<Tpoint> {
        this.x = a.x;
        this.y = a.y;
        return this;
    }
  	private inline
    function get_prop<S:Tpoint>(): Apoint<Tpoint> {
      return new Apoint( ( { x: this.x, y: this.y }: Tpoint ) );
    }
}
class Test {
  static function main() {
    trace("Haxe is great!");
    var p0 = new Apoint(new Cpoint());
    var p1 = new Apoint(new Cpoint( 1., 2. ) );
    p0.prop = p1;
    trace('p0' + p0 );
  }
}

Now it was argued that this was not possible but it's clear that the compiler can properly check constraints if you cheat.

typedef Tpoint = {
  var x:Float;
  var y:Float;
}
class Cpoint {
    public var x: Float;
    public var y: Float;
    public function new( x_: Float = 0, y_: Float = 0 ){
        x = x_;
        y = y_;
    }
}
@:forward
abstract Apoint<T:Tpoint>( T ) to T from T {
    public inline
    function new(  p: T ){
        this = p;
    }
  	public var prop( get, set ):Dynamic;
    public inline
    function set_prop<S:Tpoint>( a:Apoint<S> ):Apoint<Tpoint> {
        this.x = a.x;
        this.y = a.y;
        return this;
    }
  	private inline
    function get_prop<S:Tpoint>(): Apoint<Tpoint> {
      return new Apoint( ( { x: this.x, y: this.y }: Tpoint ) );
    }
}
class Test {
  static function main() {
    trace("Haxe is great!");
    var p0 = new Apoint(new Cpoint());
    var p1 = new Apoint(new Cpoint( 1., 2. ) );
    p0.prop = p1;
    trace('p0' + p0 );
  }
}

Now the argument can be made that because I am using Dynamic types are not checked but if I try set p0.prop = 'fred' then the compiler complains so it is fully typechecked, just I am by passing a check on the actual property.
So it must be feasible to support this currently. Obviously also there is the question of different return types so perhaps it's not desired but likely throws up some edge case that are not currently tied down?
I would be inclined to continue to use Dynamic for this case but suspect the loop hole will be removed in future.

Global using at declaration site.

The idea would is to allow using clauses on enum, interface and perhaps also class (although I don't see the use case there).

enum Option<T> using OptionTools {
  Some(v:T);
  None;
}

class OptionTools {
  static public function map<In, Out>(o:Option<T>, f:In->Out):Option<Out> { 
    /* and so on */
  }
  /* and so forth */
}

This would globally apply the static extension, but only to the type being declared. It would solve #10 - albeit in a slightly awkward way.

On interfaces it could also do some good:

interface Iterable<T> using Lambda {
  function iterator():Iterator<T>;
}

[Discussion] haxelib replacement

At latest Haxe Summit there was several discussions regarding improving or replacing haxelib.

It seems different teams have different needs when it comes to package management, be it npm integration, private repositories, frozen dependencies & versions, etc.

We think it is not the goal of Haxe Foundation to fulfill all these needs with haxelib, as it would require a lot of work for little benefit compared to other existing solutions.

However we need to provide an easy way for developers to integrate with existing package systems (npm) or even write their own.

Unlike dynamically typed languages when only runtime matters, haxe compiler requires to be able to resolve the package/libraries class paths at compilation time, it is then necessary to have a minimal protocol that resolve these classes paths and their dependencies.

Currently the haxelib protocol is commandline based. Haxe calls haxelib path lib1 lib2 lib3 (the list of libraries that are listed with -lib <name>[@version] in compiler parameters.

haxelib then prints to its output either paths or compiler parameters (which can be extraParams.hxml).

For instance when doing haxelib path heaps I get the following answer:

D:\Projects\hxtools\heaps\
-D heaps=1.0.0
D:\Projects\hxtools\format\
-D format=3.3.0

In that case haxelib resolves also the format dependency.

This is a pretty simple protocol that could be implemented by different kind of package managers adapter. We could for instance have a haxelib_npm adapter that does something similar but looks up in a npm repository instead of a haxelib one, and would print back the same output as haxelib does.

The question is the how to have the haxe compiler to call haxelib_npm instead of the (default) haxelib

I propose that we use a dot syntax for that, so the new compiler format would be:

-lib libname[.pm][@version]

Where .pm is the package manager for this specific library.
For instance you could compile with -lib mylib.npm and the classpath would be resolved by haxelib_npm adapter, or print an error if the package adapter was not found.

Some details needs to be resolved, such as the the bootstrap code that neko uses to allow to load its ndlls by doing some runtime haxelib resolution.

platform '--switch' within hxml, labeled '--next' passed with hxml call.

When building hxml I will ask my mac to open a browser.

But when creating libraries that others may try using, I want to support atleast windows,mac and linux from simple hxml build scripts, while where possible avoiding xml non generic solutions or complexity of special library run scripts.

--next
-cmd echo '<!DOCTYPE html><meta charset="UTF-8"><html><body><script src="test.js"></script></body></html>' >../binWebGL/index.html
-cmd open ../binWebGL/index.html

the simplest solution is a secondary file?

--next
--switch win: win.hxml mac: mac.hxml linux linux.hxml 

It seems minimum that haxelib should support something like --if or --switch for all currently widely used platforms, but ideally atleast just windows, mac and linux so that we can provide scripts to automatically open the browser at the very least. I am sure that I have brought this up before, and I know that any suggestions that were made to me last time did not end up being simple and practical to use on projects. It's a requirement that I have had for many years, and something that I understand is not a priority but would like it added to evolution, but would be happy with alternative hxml only solutions.

Suggestion it would be very useful to pass in a parameters

haxe compile.hxml next heapsWebGL
--next heapsWebGL
# only called if the next is in the terminal call
--next

So that any --next statement that has a parameter is only run if it is called when running the hxml, this makes it much easier to use a single hxml file without clutter of one for every target or a separate build folder that then create folder level complications and user confusion.

[PROPOSAL] Operator overload for function calls

Haxe currently allows for abstracts to redefine unary operators such as a++, as well as binary operators, such as a + b, and even other operators such as ternary, range, or array access. However, based on the documentation I have read, it does not currently allow overriding the function call operation.

I would imagine this would look something like so:

abstract CallableThing(CallableThingBase) {
  @:op(Int, Bool)
  public function call(arg1:Int, arg2:Bool):Void {
    trace('Arg 1: $arg1');
    trace('Arg 2: $arg2');
  }
}

...

var c:CallableThing = new CallableThing();
// You can now make calls to C as though it were an Int->Bool->Void function.
c(1, true);

At compilation time, c(1, true) would be replaced with CallableThing_Impl_.call(c, 1, true).

The main sticking points here is the actual syntax; @:op(Int, Bool) is redundant since we already have the function signature, @:op(()) can't necessarily be interpreted by the compiler I don't think, and the @:callable metadata is already in use.

Idea: Implicit object null test

I find myself writing a lot of statements of like the following:

if (obj == null) ...
if (obj != null) ...

Personally, I think it would be great to be able to simply write the following to make a object null test.

if (obj) ...
if (!obj) ...

What do you think; is this a good or a bad idea? And is it even possible without violating the language design?

Enum member method/variables

In language like Java you can declare methods/variables for enum right inside the enum itself:

Something like:

public enum Direction {

    NORTH, SOUTH, EAST, WEST;

    private Direction opposite;

    static {
        NORTH.opposite = SOUTH;
        SOUTH.opposite = NORTH;
        EAST.opposite = WEST;
        WEST.opposite = EAST;
    }

    public Direction getOppositeDirection() {
        return opposite;
    }
}

This looks handy but I am not quite sure about the difficulty of implementing it and any negative consequences to the language. So I would like to gain some more knowledge about the topic before writing a proposal

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.