Skip to content

Simplify the definition and use of custom index operators#69

Closed
Octachron wants to merge 4 commits intoocaml:trunkfrom
Octachron:index_operators
Closed

Simplify the definition and use of custom index operators#69
Octachron wants to merge 4 commits intoocaml:trunkfrom
Octachron:index_operators

Conversation

@Octachron
Copy link
Member

This patch simplifies the definition and use of custom index operator, i.e the
operators used to access or modify the value of an array-like structure at an given index.

First, a new syntax for index operators is introduced.
Six "core parenthesis operators" are added

  • .() ,
  • .[] ,
  • .{}, .{,}, .{,,}, .{,..,}.

The .{,}/.{,,}/.{,,,} operators are defined for compatibility with the
Bigarray syntax extension (more about it later).
Each core index operator is available in an safe/unsafe and access/assignment
versions. For instance, .() is declined in

  • .() : safe index operator
  • .()! : unsafe index operator
  • .()<- : safe indexed assignment operator
  • .()!<- : unsafe indexed assignment operator

Expressions of the form array.(index), string.(index) and bigarray1.{index} are
now desugared to one of these new index operators. The safe or unsafe index
operator are chosen in function of the presence or absence of the
"unsafe" compiler option.
These new index operators respect the -unsafe
compiler option using new compiler primitives.

In order to keep the compatibility with existing code,
the .() and .[] index operators are defined inside the pervasives modules
to be equal to their standard equivalent.

Compatibility issues with bigarray

The bigarray .{} operators can be desugared to 4 different operators to
respect the original bigarray syntax extension.

More precisely, the index operator used in the desugaring changes if the
index is a n-tuple. Depending on the arity of the tuple, the index operator
used is either:

  • 1-tuple => .{} : arity 2 [ +1 for assignment ] operator
  • 2-tuple => .{,} : arity 3 [ +1 for assignment ] operator
  • 3-tuple => .{,,} : arity 4 [ +1 for assignment ] operator
  • 4 and more tuples => .{,..,} : arity 2 [ +1 for assignment]
    operator, the tuple is passed as an array.

The bigarray module have been updated to use these new operators. However,
since these operators are not defined inside pervasives, this change will
break
existing code using bigarrays without opening the Bigarray module.
At least one test in the test suite has been updated due to this
incompatibility.

An other possibility to deal with this incompatibility issue
would be to hide the new desugar transform of .{} behind a compiler switch.
A possible advantage of this compiler switch option is that it would
allow to fusion all four .{} operator. Then, the bigarrays custom .{} index
operators could be implemented at the Bigarray.Array{n} level rather than
the Bigarray level.

Other compatibility issues

Code relying on the old desugaring to redefine the index operators will also break.

Example of code

type z = Zero
type 'a succ=Succ
type (_,_) nat = Z : ('a,'a) nat | S : ('a,'b) nat -> ('a, 'b succ) nat

type  'dim vector = ((z,'dim) nat * float array )

let rec to_int: type inf sup. (inf,sup) nat -> int = 
function Z -> 0 | S n -> 1  + to_int n 

exception Wrong_dimension
let from_array : type dim. (z,dim succ) nat -> float array -> dim vector = 
fun (S nat) array ->  if (Array.length array=1+to_int nat) then 
 (nat, array) 
else
 raise Wrong_dimension

let ( .{} ) : 'dim vector -> ('mid,'dim) nat ->  'float  =
 fun (dim,v) nat -> Array.unsafe_get v (to_int nat)

let ( .{} <- ) : 'dim vector ->  ('mid,'dim) nat -> float -> unit  =
fun (dim,v ) nat x -> Array.unsafe_set v (to_int nat) x

let a = from_array (S (S Z)) [|1.;2.|]

let x = a.{Z}
let () =  a.{S Z} <- 11.

Edited on 13/06/2014 to reflect the current version of the proposal

@gasche
Copy link
Member

gasche commented May 25, 2014

I like the change, but I'm less convinced by the ! versions of the operator. My understanding is that you need it to not special-case the way the array-sugar uses unsafe_get sometimes, but the downside is that the bang-using operators do not have a sensible "applied syntax", contrarily to the other.

@samoht
Copy link
Member

samoht commented May 25, 2014

That sounds quite an interesting extension! Seems that can encode python-like dictionaries using your {}:

let ( .{} ) = Hashtbl.find
let ( .{} <- ) = Hashtbl.update

let () =
  let t = Hashtbl.create 1024 in
  t.{ "foo" } <- 1;
  t.{ "bar" } <- 2;
  t.{ "foo" }

@pw374
Copy link

pw374 commented May 25, 2014

Awesome idea! I look forward to that being implemented in the standard distribution.

@Drup
Copy link
Contributor

Drup commented May 25, 2014

Would it be possible to add custom operators ? Following the ocaml convention, something like "start with {, ( or [, end with the corresponding closing symbol". .(| ... |), .[^ ... ^] and so on.

@gasche
Copy link
Member

gasche commented May 25, 2014

A previous related proposal (for monadic operators rather than index-access operators) was shot down as too complex after we started arguing about which custom operators were reasonable. If I were you, I would first concentrate on a minimum viable proposal, and revisit the "custom operators" idea a few versions later.

@Drup
Copy link
Contributor

Drup commented May 25, 2014

@gasche You're probably right, I don't want to start this kind of discussion.

@Octachron
Copy link
Member Author

@gasche I agree that the ! version of the operators are less than ideal and even potentially
dangerous. They are here to mirror exactly the current behavior of the -unsafe compiler option.
In presence of this option, the compiler switch the desugaring of a.(b) to Array.unsafe_get
rather than Array.get. I don't see right now a way to implement this behavior without two different
variants of each index operators. However, if this behavior was deprecated, one possibility
would be to add an Unsafe submodule to the concerned modules: In order to emulate the previous
behavior of the -unsafe compiler option, one would only need to open the Array/String/Bytes/Etc.Unsafe module. The granularity would be better but it would imply even more modifications to existing code.

@Drup The problem with adding custom operators is also that it becomes more difficult
to predict the interaction with all the specialized parenthesis, present and future. For instance, what about
[% or [@?

@lpw25
Copy link
Contributor

lpw25 commented May 25, 2014

@Octachron I believe you could avoid the unsafe variants by adding a module camlinternalArray to the stdlib which contains declarations like:

external get : 'a array -> 'a = "%array_opt_get"
external set : 'a array -> 'a -> unit = "%array_opt_set"

and exposes them as externals in the interface. By exposing the externals in the interface, they are guaranteed to be inlined when used. This means that the behaviour of the %array_opt_get and %array_opt_set compiler primitives can be controlled by the -unsafe option.

EDIT: Actually, I suppose you are defining .() in Pervasives, so using a camlinternalArray module would place the inlining in the wrong place. Instead .() should itself be exposed as an external by Pervasives. This might affect code which used (module type of Pervasives), but hopefully no one actually does that (and if they do it's their own fault).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The desugared examples here and and in the following ocamldoc comments should probably be wrapped in [] so that it is properly marked up by ocamldoc:

... is desugared to [( .() ) a index] if the ....

@Octachron
Copy link
Member Author

@lpw25 Thank you for your suggestion. Using new compiler primitives for the index operators
works. With this, the ! versions of the index operator can be removed.
@hcarty I have updated the documentation.

This new version removes the ! version of the index operators. The -unsafe compiler option
is handled using new compiler primitives for string, array and bigarray index operators.
This new primitives are then transformed to the standard safe/unsafe get/set depending on
the -unsafe compiler option. Consequently, the -unsafe can no longer trigger compiler error
when the unsafe ! operators have been forgotten.

@chambart
Copy link
Contributor

In fact this can break some code of users relying on the orignal 'feature'.
I had, and know at least one other person who used that trick:

module S = struct
  module Bigarray = struct
    module Array1 = struct
      let get x y = Hashtbl.find x y
      let set x y z = Hashtbl.add x y z
    end
  end
end

let t = Hashtbl.create 1
let _ = S.(t.{1} <- 'x'; t.{1})

@Octachron
Copy link
Member Author

True. This change would break any code relying on the (undocumented?) original desugaring
to redefine the index operators. However, translations to the new syntax should be simple.

If really needed, I think a ppx extension could even do the translation automatically.

Anyway, this incompatibility should be documented.

@rizo
Copy link

rizo commented Jul 16, 2014

The case of python-like hashtable accessors is terrific, can't wait to see it in the official distribution.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here the assign variable is a string, for bigarray_function it is a boolean.

Is there a reason for that ?
Maybe we should have a unified way of calling those two functions, the boolean way seems cleaner.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No good reason as far as I can see.
I was probably initially mimicking the original function, then realized that there was only two possible value for assign while writing bigarray_function.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested the above lines and it wouldn't work: Translcore is linked before the arguments are evaluated, so in this case, !Clflags.fast is always set to false.

Those should go directly in the find_primitive function below.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. I have fixed this problem in the current version. Thank you for taking the time to test this point.

@bobot
Copy link
Contributor

bobot commented Nov 11, 2014

This PR have been discussed during the last developers' meeting, where I had the pleasure to be. To sum-up:

  • Problem with evaluation time as @thomasblanc commented, must be fixed
  • Otherwise reasonable, ok for integration.

@Drup
Copy link
Contributor

Drup commented Nov 12, 2014

Nice to see this is considered for integration!

@bolot thank you for the reports on the various pull request, It's very nice for people who can't go to developers meetings.

This commit introduces a new syntax for index operators.
Six core parenthesis operator are added:
.(), .[], .{}, .{,}, .{,,}, .{,..,}.
The .{,}/.{,,}/.{,,,} operators are defined for compatibility with the Bigarray syntax extension.
Each core index operator is available in a access/assignement versions. For instance, .() is declined in
* .() : index operator
* .()<- : indexed assignment operator
The general syntax for these index operators as implemented in the parser is index_operator::= index_operator_core [<-]
This commit modifies the parser to use the newly defined .() and .[] operators. It also moves the definition of the standard .() and .[] operator for String/Bytes and Array to the pervasives module.

Before this commit, expressions of the form array.(index) and string.(index) where desugared to Array.get[_unsafe] array index and Strinf.get[_unsafe] string index. The unsafe or unsafe version were chosen depending on the presence of the "-unsafe" compiler option. Such expression are now desugared to ( .() ) array index and ( .[] ) string index respectively. The same desugar operation is applied to array.(index) <- value which becomes ( .()<- ) array index value.

In order to keep the standard semantic for the string and array index operations, these new index operators are defined in the pervasives module using new compiler primitives, e.g.
let .() = "%array_opt_get".
These new primitives are then mapped to safe or unsafe version depending on the
the "-unsafe" compiler option. Consequently, these modifications should have no impact on existing code.

With these modifications, defining custom .() and .[] operators should be easier, at the cost of losing access to the standard index operator for either array or string.
This commits modify the Bigarray syntax extension in order to facilitate the use of custom .{} operators. The compatibility with the existing Bigarray syntax has been preserved as much as possible. However, this commit will break code which use the Bigarray .{}
syntax without opening the Bigarray module first!

Like the previous commit, this commit modifies the parser to desugar bigarray1.{index} to ( .{} ) bigarray1 index. Following the bigarray syntax, the index operator used
in the desugaring changes if the index is a n-tuple:
1-tuple => .{}
2-tuple => .{,}
3-tuple => .{,,}
4 and more tuples => .{,..,}

The bigarray modules has been modified to use this new index operators. Note that this means that these index operators are not anymore accessible without opening the bigarray module.
@Octachron
Copy link
Member Author

@bobot Thanks for the information

I have rebased the pull request and cleaned it a little following the suggestions of @thomasblanc.
The -unsafe option should now produce the expected segmentation fault.

@lpw25
Copy link
Contributor

lpw25 commented Nov 17, 2014

The 4 levels of the bigarray operators is a bit arbitrary. Could we instead expose just:

  • 1-tuple => .{} : arity 2 [ +1 for assignment ] operator
  • 2 and more tuples => .{,} : arity 2 [ +1 for assignment] operator, the tuple is passed as an array.

and then add a simple optimisation for the %caml_ba_indexop_ref_n primitive to detect the case with 2 or 3 arguments (in a similar way to how the safe/unsafe variants now work).

The only downside I can see is that custom operators wouldn't be able to have optimised versions for 2 and 3 indices, but they already can't optimise for 4 or higher so it doesn't seem too bad. Ideally, inlining and unboxing optimisations would remove the extra cost from array allocation anyway.

@hcarty
Copy link
Member

hcarty commented Nov 17, 2014

I like @lpw25's suggestion because, with that approach, it would be simpler to support the array form for all indexing operators. There's nothing special about the .{} operator at this point.

@Octachron
Copy link
Member Author

@lpw25 I agree that the 4 levels of bigarray operators are a bit too arbitrary.
I don't really like to have that many operators but they are necessary for backward compatibility with
Bigarray:

.{} : Bigarray.Array1.t -> ... 
.{,}: Bigarray.Array2.t -> ...

and the Bigarray.Array{n}.t types are abstract.
It is not an ideal situation but I am not completely convinced either by the division between .{} and .{,}. If we were breaking compatibility withBigarray, I would prefer a more uniform solution.

@hcarty
Copy link
Member

hcarty commented Nov 17, 2014

@Octachron If the current "1, 2, 3, array" approach is kept for Bigarray compatibility is there any reason not to extend the same support to the other index operators?

@Octachron
Copy link
Member Author

@hcarty The implementation of this extension would be quite straightforward.

However, this feature would interfere a little with the simple version of the .()/.[] operator.
Without this feature,

 a.[x,y] 

and

let p = x, y in 
 a.[p] 

are equivalent. There are not equivalent anymore when .[,] is introduced because

a.[x,y] = (.[,]) a x y

whereas

let p = x,y in 
 a.[p] 
= (.[]) a p

Of course, fixing this problem is easy enough: if .[] takes a tuple in argument, the corresponding
.[,..] operator must be also defined. But this does mean that the complex option leak into the simple one.

Another point is that I have the impression that most of the use of .{,..} could be solved using a mixture of GADT and phantom types.
For instance, in Bigarray, .{} could be implemented as

type z=Nil_zero
type 'a succ = Nil_succ
type ('ph,'a,'b,'c) Genarray.t = ( 'a,'b,'c) Genarray.t
type 'ph n_list = T : z n_list | Cons : int * 'n n_list  -> 'n 'succ n_list
let ( *: ) (x:int) l =  Cons x l
let ( .{} ) a:('ph,'a,'b,'c) indices:'ph n_list   = ...
...

Then a.{ 1 *: 2 *: T } would have more static guaranteed than the current version of Bigarray.

Speaking about Bigarray, there is a way to implement Bigarray with simply (.{}) and (.{,}) without losing the distinction between the Array{n}.t type : we can add a phantom type to Genarray.t and a type witness at the parser level. Something like

(.{} ) : ('type_integer, 'a,'b,'c ) Genarray.t -> 'type_integer * int array -> 'b 

It would complicate the Bigarray module but it should be possible to preserve the current semantic. But like the 4 version variant, we still lose the equivalence a.{x,y} = a.{2-tuple}.

In brief, I see 3 possible stopping points

  • Statu-quo: A 4-version operator for .{}, only one version for .[] and .(). The operator .{} is the only one which breaks the equivalence between a.{x,y} and a.{tuple}
  • Second option: All three operators implement the 4 versions.
  • Third option: All three operators implements the 2 versions .{} and .{,} where the second argument of ".{,}" is a pair (array,type witness to the number of argument).

Personally, I quite like the third option. But it sounds too complex to be integrated in this pull request.
Simultaneously, I am quite neutral concerning the second option, do you have any use case in mind @hcarty?
Anyway, if the need arise in the future, it should be relatively straightforward to extend the current version to one of these two extensions.

@gasche
Copy link
Member

gasche commented Nov 17, 2014

You must keep it simple, and I think the statu quo is the best option in this regard. Multi-dimensional bigarrays are by now a historical curiosity, they can stay a bit peculiar.

@gasche
Copy link
Member

gasche commented Nov 19, 2015

Sorry for the terse writing above (I was trying to give feedback as soon as possible to the many change proposals that have been discussed, but evidently did a bad job at communicating here).

There is nothing secret about Leo's proposal, except that he prepared some slides/presentation for the meeting that are not online yet ( @lpw25 , could you make them publicly available somewhere?). It is work that originated from an effort to remove the special-casing of float arrays in the current OCaml runtime. You can find some early description of the idea in this comment on a proposal by Alain Frisch related to float arrays. Leo then developed a more complete proposal of what he calls "array data types", whose implementation can be found in his array-data-types branch, where a new type constructor for arrays is introduced with attributes to provoke various kind of specializations (mutable/immutable, unboxing, zero-termination, with the default being generic, non-float-specialized arrays).

The key point of his proposal that is of concern here is to consider these specialized array types as glorified records, where the array-indexing operation .() and .()<-, and a length projection .length have a status similar to record field projections -- in particular, they are disambiguated in a type-directed way, instead of being overloaded by scope as in your proposal.

It is not yet clear that this aspect of the proposal is bound to stay, but I think it is interesting enough (obviously for record projections type-based disambiguation is much more usable than scope-based usage, and as the complex discussion on shadowing warnigns show, local open are no panacea) to give us pause and some time to think harder about where we want to take indexing operators.

Having .() type-disambiguated and .[] scope-disambiguated is a proposal of Leo, and honestly I think it makes no sense. If we find out that the type-directed strategy is indeed better, it will surely be better for .[] as well (think of bytes vs string for example), and conversely if scope-based is a better design in terms of user applicability, then I think this aspect of Leo's proposal should be rejected. We are trying to find a good design, not play politics and make compromises to please the involved parties. (I'm not saying I would be against all hybrid designs, but there would need to be a very strong justification for mixing both strategies.)

We are trying to move to a shorter release cycles, ideally six-month releases. The choice here is not to definitely reject your feature (scope-based user-defined indexing overloading), but rather to not include it in the next release (4.03) and postpone an inclusion choice to 4.04 -- hoping to have advanced in the consideration of these competing designs. Language design is a conservative affair.

When I speak of a branch, I am thinking of having a scoped-indexing-operators branch in the development repository, that would be synchronized with trunk -- so that at any point in time it is easy to build a version of the distribution with the feature enabled, for experimentation or for specialized usage. I'm not asking you to maintain it -- but I'm not promising either that I will personally have the time to do so.

(Let me point out that the Bigarray-related compatibilty woes were not instrumental in taking this decision. Nor are their your responsibility, it's clear that at the time the feature was integrated there was consensus that not special-casing Bigarray was the right choice -- but this was proved wrong by practical experience with trunk compatibility. In fact we had discussed them separately before taking this reversion decision, and had decided to go the conservative way of implicitly opening Bigarray.Operators an .{..} operator was used with none in scope.)

@lpw25
Copy link
Contributor

lpw25 commented Nov 19, 2015

@lpw25 , could you make them publicly available somewhere?

I didn't have any actual slides, but the branch is available at https://github.com/lpw25/ocaml/tree/array-data-types. It doesn't have any documentation to explain the syntax, since I haven't added tests yet, so that may not be very useful for understanding the feature.

Having .() type-disambiguated and .[] scope-disambiguated is a proposal of Leo, and honestly I think it makes no sense.

I disagree. Whilst the current patch doesn't do this yet, it is sufficient to use ".()" for both regular arrays and strings (and bytes etc.), in fact that is a benefit of the proposal: ".()" becomes an explicit projection from an array(-like) block. However, it means that ".()" is always restricted to types which are implemented as array(-like) blocks. Since many other types may usefully have some notion of projection it makes sense to also separately provide an operator that can be over-loaded for those types and it seems reasonable for ".[]" to be that operator.

@lpw25
Copy link
Contributor

lpw25 commented Nov 19, 2015

As a side-note, my array data types proposal -- in common with ordinary labels -- supports the syntax:

foo.FloatArray.(0)

which avoids the need for local open. I think a similar syntax would be useful for ".[]".

@Drup
Copy link
Contributor

Drup commented Nov 19, 2015

I have trouble to understand how you can't do all that with the current proposal + implicits (and an Indexable signature), and without more insight, I don't see how @lpw25's proposal is likely to get integrated before implicits.

@lpw25
Copy link
Contributor

lpw25 commented Nov 19, 2015

I have trouble to understand how you can't do all that with the current proposal + implicits (and an Indexable signature)

It's difficult to explain without fully explaining the proposal -- so best to wait until I've found time to do that.

I don't see how @lpw25's proposal is likely to get integrated before implicits.

The proposal is already mergeable whilst implicits still requires a huge amount of work.

@Octachron
Copy link
Member Author

@gasche:

Thanks for taking the time to detail your comment. I have no doubt that you were well meaning in your previous comment. However, communicating decisions without the context of the decision is bound to create some frictions from time to time. If there is any plan to have some publicly available minutes of the developer meeting? It would be very nice; the difference between a secret and an information shared only with a select circle is tenuous at best.

After reading the explanation for Leo proposal, it sounds like a nice feature; that does not cover any of my uses case for custom index operators (e.g dictionary, slice, multidimentionnal array or statistically checked array ) where either the data is not exactly an array block or the index is not a simple integer. In these more complex situations, I still think that it makes more sense to have scope-overloaded index operators. So I agree with @lpw45 that it might make sense to have .() for "true" array type and .[] for indexable type ( and .{} for use cases that match bigarray semantic accidentally ).

We are trying to move to a shorter release cycles, ideally six-month releases. The choice here is not to definitely reject your feature (scope-based user-defined indexing overloading), but rather to not include it in the next release (4.03) and postpone an inclusion choice to 4.04 -- hoping to have advanced in the consideration of these competing designs. Language design is a conservative affair.

The shorter release cycles sounds like a good news. This is also the kind of news for which having minutes would be nice. And like I said before, I understand the thirst for further considerations -- just does not expect me to be perfectly happy if these considerations take place behind closed doors.

When I speak of a branch, I am thinking of having a scoped-indexing-operators branch in the development repository, that would be synchronized with trunk -- so that at any point in time it is easy to build a version of the distribution with the feature enabled, for experimentation or for specialized usage. I'm not asking you to maintain it -- but I'm not promising either that I will personally have the time to do so.

In this context, i.e. limited period and well-defined objective, I will be glad to lend an hand to maintain this branch.

@lpw45:

I agree that the syntax array.Module.{..} is a nice way to avoid both local open and custom ascii art operators. Originally, I was thinking to propose this extended syntax after 4.03. Let's say that I am a little bit wary about such extensions now.

@gasche
Copy link
Member

gasche commented Nov 19, 2015

If there is any plan to have some publicly available minutes of the developer meeting?

I am currently in the process of "exporting" the decisions that have been made as publicly-visible comments on the tickets that have been discussed. I did a bit yesterday (obviously I over-favoured quantity over quality of the reports), and hope to finish today. (It's actually quite a bit of work.)

We do need to improve communication on release cycle decisions and such (I'm trying to mention it explicitly in the present reports), but I'm uncomfortable with the idea of exporting minutes for a meeting without having had agreement of the various participants beforehand. For this one meeting I think I'll keep a summary-only approach. (I don't expect to be present in similar meetings in the short- to medium-term future, but maybe @bobot or other participants could take a decision on this. )

@lpw25
Copy link
Contributor

lpw25 commented Nov 19, 2015

but I'm uncomfortable with the idea of exporting minutes for a meeting without having had agreement of the various participants beforehand.

I think a summary of the discussions (rather than full minutes) would be useful in addition to the individual feedback to PRs as it gives a single place people can read about the various discussions. I also agree that the agreement of the participants is needed before releasing such a summary. Perhaps if you wrote a small summary from your notes, and asked on caml-devel for the approval of the participants, they could be posted somewhere (although I'm not sure where the best place would be).

@alainfrisch
Copy link
Contributor

The minutes would also be useful for caml-devel itself since not all core developers could attend the meeting. For a larger diffusion, we would also need to get the green light from non-core devel participants.

@mshinwell
Copy link
Contributor

@damiendoligez As far as I recall from the recent meeting it was decided that this should not be merged; do I remember correctly? If so we should probably close this.

@Octachron
Copy link
Member Author

@mshinwell I have more mixed memories on this discussion, however it would be clearer to close this PR (and #622) in favor of its latest incarnation #1064 .

@Octachron Octachron closed this Mar 7, 2017
@damiendoligez
Copy link
Member

My notes agree with @Octachron

stedolan pushed a commit to stedolan/ocaml that referenced this pull request Mar 21, 2023
c703f5f Incorporate upstream comments into type-variable refactor (ocaml#121)
362ba23 Constrain curry modes to increase along applications (ocaml#108)
b1f0cf9 Simplify the extension handling (ocaml#114)
4fd53a1 Remove pat_mode from typedtree (ocaml#105)
cf6fcbc Handle attributes on lambdas with locally abstract types (ocaml#120)
5fa80fe Don't track attributes inside attributes for warning 53 (ocaml#115)
8a69777 Handle unclosed `[: ... :]` patterns (via `Generic_array` machinery) (ocaml#117)
b0737f4 Add promote-one Makefile target (ocaml#118)
c6ad684 Refactoring and fixes around module lookup (ocaml#107)
b0a6495 Add documentation for global constructor arguments (ocaml#69)
dd79aec Print `nlocal` in the `-d(raw)lambda` output (ocaml#112)
8035026 Fix `nlocal` in the generated Lambda for list comprehensions (ocaml#113)
afbcdf0 Immutable arrays (ocaml#47)
bfe1490 fix several issues when removing exp_mode (ocaml#110)
8f46060 Better error message for under-applied functions (ocaml#74)
27331d8 Consistently use Lmutvar or Lvar in comprehensions (ocaml#111)
01e965b Skip failing test for now
0131357 Fix test case to use comprehensions_experimental
22a7368 Temporarily disable list comprehensions tests due to locals bug
e08377d Make `comprehensions` into `comprehensions_experimental` for now (ocaml#109)
947cf89 List and array comprehensions (ocaml#46)
bd9e051 remove exp_mode from typedtree (ocaml#100)
a9268d2 Fix misplaced attribute warning when using external parser (and some cleanup) (ocaml#101)
2b33f24 Refactor toplevel local escape check (ocaml#104)
ed2aec6 Comment functions exported from TyVarEnv.
87838ba Move new variable creation into TyVarEnv.
a3f60ab Encapsulate functions that work with tyvars
43d83a6 Prevent possibility of forgetting to re-widen
2f3dd34 Encapsulate context when narrowing type env't
d78ff6d Make immediate64 things mode cross (ocaml#97)
aa25ab9 Fix version number (ocaml#94)
d01ffa0 Fix .depend file (ocaml#93)
942f2ab Bootstrap (ocaml#92)
05f7e38 Check Menhir version (ocaml#91)
1569b58 Move the CI jobs from 4.12 to 4.14. (ocaml#90)

git-subtree-dir: ocaml
git-subtree-split: c703f5f
EmileTrotignon pushed a commit to EmileTrotignon/ocaml that referenced this pull request Jan 12, 2024
EmileTrotignon pushed a commit to EmileTrotignon/ocaml that referenced this pull request Jan 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.