-
-
Notifications
You must be signed in to change notification settings - Fork 654
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
further work on final? #6615
Comments
Don't forget that haxe-generated code can be used from a 3rd party code. In that case user should be able to cancel "final" optimization on specific fields. |
Yes I don't think we should start inferring Regarding structure notation, it is supported, but locks you into structure notation. This is a parsing problem because we can't distinguish the two until we see the separator. I'm not sure what we can do here... Regarding inferring |
I think not allowing To me at least it would be far more useful if a complex type starting with |
Shouldn't it lock you into class notation? Since
Surely not,
I would also love "immutable" type modifiers, but I think that's a different and more complex matter that needs much more design and discussion. In fact I even started writing a proposal about that months ago. The current |
Evidently, I am once again failing to express what I mean. I do not wish to inflate the issue towards C++ typedef StyleObject = {
@:optional var alignContent(default, never):String;
@:optional var alignItems(default, never):String;
@:optional var alignSelf(default, never):String;
@:optional var alignmentAdjust(default, never):String;
// ... >300 more fields here
} So there's typedef StyleObject = final {
?alignContent:String,
?alignItems:String,
?alignSelf:String,
?alignmentAdjust:String,
// ... 300 more fields here
} (Actually, I would still argue that different syntax should have different semantics and therefore structures should be "final" and for anything else you should use class field notation, but whatever ...). And yes, every field may hold mutable data. This is perfectly fine, because sometimes it's actually desired. In other words: typedef HasIntArray = final {
array:Array<Int>
}
//Is fully equivalent to
typedef HasIntArray = {
final array:Array<Int>;
}
//and given
var o:HasIntArray = { array: [1, 2, 3] };
//this compiles:
o.array.push(12);
//and this doesn't
a.array = [1, 2, 3, 12]; I hope this makes a bit clearer what I want and why. |
Well that's what typedef StyleObject = {
@:optional final alignContent:String;
@:optional final alignItems:String;
@:optional final alignSelf:String;
@:optional final alignmentAdjust:String;
// ... >300 more fields here
}
Sometimes yes, sometimes no. In my project I actually want C++-like recursive By the way, regarding these pesky typedef StyleObject = {
final? alignContent:String;
final? alignItems:String;
final? alignSelf:String;
final? alignmentAdjust:String;
// ... >300 more fields here
} The |
Yes, that is precisely why we chose typedef User = final {
id:Int,
name:Observable<String>,
blocked:State<Bool>,
} So yes, the Right now, I have to write this: typedef User = {
var id(default, never):Int;
var name(default, never):Observable<String>;
var blocked(default, never):State<Bool>;
} This is a bit of an improvement: typedef User = {
final id:Int,
final name:Observable<String>,
final blocked:State<Bool>,
} But really, this is what I want: typedef User = final {
id:Int,
name:Observable<String>,
blocked:State<Bool>,
} An yes, as the system grows, the |
So you basically just want to have typedef User = Final<{
id:Int,
name:Observable<String>,
blocked:State<Bool>,
}>; Anyway, I still think that |
Makes sense |
Look, if you have no use for this, ok fine. That's your prerogative. But to say it's "random" is just non-sense, because such final structures are pretty much exactly how records work in standard ML. They are immutable, but they may hold refs (which themselves are mutable). Even Haskell records can hold mutable stuff like MArray.
I know that. You know I know that. I know you know I know that. And we also both know you have made your argument against resorting to such workarounds in your |
Uhm, I didn't say I don't have use for immutable records, the "randomness" point was about this particular syntax extension for short structure notation syntax. I don't have a strong position on that, just sharing my opinion. I even added "a bit", you know. Why such drama? Regarding my arguments against macro approach: most of them apply only to the recursive const I was proposing specifically. The |
That's not how I would read this:
But fair enough. If what you're saying is all about the syntax, we fully agree. It is random, as is
If this is your implementation, then the recursion is expensive because you're not caching sufficiently, e.g. in |
I think we also should consider |
We have added both |
If you deprecate |
Replacing |
I'll close this to focus on #6584. |
I have a couple suggestions/question regarding the new
final
feature:How about inlining
static final
fields when they are initialized with a constant? This would effectively deprecatestatic inline var
, which a lot of users find weird and I think it would make the language easier to learn.final
doesn't seem to be supported for anon structures class notation, e.g.{final x:Int;}
currently givesUnexpected ;
error. Is this intentional or it's a bug?Not really related to
final
keyword feature, but I think we need a (maybe optional) post-process filter that will add "final" to fields and classes that are not extended/overriden in current compilation. I think it's useful for performance (providing static dispatch instead of vtable in a lot of cases), and IIRC something like this is already done for Hashlink target on generator-level. Maybe we could have this as a general optimization?The text was updated successfully, but these errors were encountered: