Julia: Syntactic sugar for ignoring a type parameter

Created on 31 Oct 2018  Â·  14Comments  Â·  Source: JuliaLang/julia

Consider

struct Foo{A, B, C, D}
end

and we want to write a binary function where D has to match.

Possibilities:

foo(A::Foo{A1, B1, C1, D}, B::Foo{A2, B2, C2, D}) where {A1, A2, B1, B2, C1, C2, D} = ...
foo(A::Foo{<:Any, <:Any, <:Any, D}, B::Foo{<:Any, <:Any, <:Any, D}) where {D} = ...

How about:

foo(A::Foo{_, _, _, D}, B::Foo{_, _, _, D}) where {D} = ...

?

Using _ as an rvalue is deprecated so could this should be available?

parser

All 14 comments

Related: https://github.com/JuliaLang/julia/pull/24990. These don't necessarily conflict since we can special case the interior of T{...} but it's worth paying attention to.

Triage: Will wait a bit for the eventual resolution of #24990

This is a very good proposal. I am impatient to see this in Base !

After years of discussion, 214 comments over there, what about unsyncing of #24990 to follow its own way...

As I wrote over there, #24990 is

Designed and I think largely agreed upon but requires a different implementation

so it's not as if no progress has been made and this proposal conflicts with that one.

Thanks for your feedback. I have read your comment before previously posting,
and have seen it has occured monthes ago, nearly quarters ago now.
I must confess i find it's very hard to track the state of major proposal on github issues / discourse.
214 comments! Good if consensus is reached and momentum is kept.

You will now have

Foo{_, _, _, D} where {D} rather than Foo{A,B,C,D} where {A,B,C,D}. Much leaner

I also suggest to consider

  • Foo{_, _, _, <:Baz} equivalent to Foo{_, _, _, _<:Baz}
  • Foo{_, _, _, >:Bar} equivalent to Foo{_, _, _, _>:Bar}

bonus

  • Foo{_, _, _, Bar<:_<:Baz} no equivalent in short form nowaday, neither later

That will consolidate short forms and bring them to same level of capabilities than long where ones.
where can become a kind of scope expander (to function body), factorizer (your first proposal with constraint on D will better fit a factorized clause in where rhs rather than redeveloped @ A::, B::).

This is certainly a nice feature, but again, the syntax collides with #24990. The question is which feature is more useful/important and worth getting this bit of syntax? You can already use <:Any for many of these.

I understand your concern about the timeframe and mutual impact.
You have been clear enough. The point is not to discuss this anymore.

This is just a note to consider when time of choice and/or implementation will come.
Cordially

--
My point of view is that there will be some echo, for sure, but not necessarly insuperable conflict

Another case to consider (coming from porting of rust code to julia)

abstract type Result{O,E} end
struct OK{O} <: Result{O,_}; value::O end
struct Err{E} <: Result{_,E}; value::E end

seems clearer than

abstract type Result{O,E} end
struct OK{O,E} <: Result{O,E}; value::O end
struct Err{O,E} <: Result{O,E}; value::E end

Why not save _ for #24990 and use

foo(A::Foo{, , , D}, B::Foo{, , , D}) where {D} = ...

? Not having placeholders like _ is probably not the most elegant syntax. But I guess it's at least not ambiguous?

Quoting big boss JeffBezanson

That's the problem with special syntax; there's never enough of it.
https://github.com/JuliaLang/julia/issues/19198#issuecomment-257970722

Code is 90% reading, 10% writing, and sorry, but special form are childhood diseases there.
The proper way to go is to handle context properly in parsing. We have the chance to deal with context-free grammar in programming language (eg. choosen and explicit context only), it should be used and abused. That's really lucky, NLP practitioner in lisp could have experience the shift in mindset.

About #24990. Nothing personal there but, engineers have to consider some facts about it:

  • LOC: 83 lines
  • Forum posts: 214
  • Duration : 726 d

Giving the following ratio

  • Forum post per 10 loc : 26
  • LOC per month: 3.5

Neither a good way to contribute to foss, neither a foundational work in any way at this stage.

Code is 90% reading, 10% writing, and sorry, but special form are childhood diseases there.

None of the current ways of doing this

foo(A::Foo{A1, B1, C1, D}, B::Foo{A2, B2, C2, D}) where {A1, A2, B1, B2, C1, C2, D} = ...
foo(A::Foo{<:Any, <:Any, <:Any, D}, B::Foo{<:Any, <:Any, <:Any, D}) where {D} = ...

seem easy to read so not sure what point you are trying to make?

Neither a good way to contribute to foss, neither a foundational work in any way at this stage.

A metric like number of lines per month a PR has been opened seems like a bad way to measure progress. Not all lines of code are equal.

Contrary to #24990 this proposal is actually consistent with the current meaning of _ being a sink to function arguments, extending it to function argument types.

Was this page helpful?
0 / 5 - 0 ratings