On Thu, Jun 18, 2009 at 3:28 PM, john skaller<skal...@users.sourceforge.net> wrote: > > still not sure what to do about this. This cannot work now: > > x.[i] += 1; > > where x is a C-array, because the subscript function cannot return > an lvalue (since they don't exist). It could return a pointer, and we could > make it so > > p + 1 > > actually means > > *p + 1 > > Normally deref and store are the only operations allowed on pointers, > addition (as in C) isn't allowed. At present > > a.[i] = 1; > > only works because of a hack: Felix doesn't bother to actually check > the LHS here is legal. This should mean > > &a.[i] <- 1; > > which would fail, but assignment is simply delegated to C.
Oiy, isn't this a big can of worms? So starting off, I still think it's a good idea that we got rid of lvalues. There are a bunch of things at work here. I think the main question is if arrays are special. In C/C++, we can limit pointers through const-ing. It has 4 types of pointers: int i[] = { 1, 2, 3 }; int j[] = { 3, 4, 5 }; int* p = i; p[0] = 0; p = j; const int* p = i; p[0] = 0; <- type error p = j; int* const p = i; p[0] = 0; p = j; <- type error const int* const p = i; p[0] = 0; <- type error p = j; <- type error However, they don't transmit immutability. It's pretty simple to take a `const foo* const` and modify it: struct P { int x; int y }; const P const p[] = ... p[0].x = 5; This means it's easy to create a data structure that is only sort-of immutable. OCaml, on the other hand, treats it's arrays as always mutable. With references, OCaml essentially provides "int*" and "int* const" semantics: # let f a = a.(0) <- 5;; # let a = [|1;2;3|];; # f a;; # a;; - : int array = [|5; 2; 3|] Scala works the same way. Felix currently works the same way by default: # proc foo[N] (x:array[int,N]) { x.[0] = 5; } # val x = 1,2,3; # foo x; # println x; -: (5, 2, 3) However, we can limit this by using the "var" keyword: # proc foo[N] (var x:array[int,N]) { x.[0] = 5; } # val x = 1,2,3; # foo x; # println x; -: (1, 2, 3) But there's no way to say "it's a type error to modify this array" like C/C++ does. So, is this something we'd want? I personally think something like this would be useful, and I'd bet it'd help with optimization. We'd probably want something like this to work beyond just arrays and pointers. One way we could limit this a little bit is to make value arrays immutable, where these would be type errors: # val x = 1,2,3; # x.[0] = 5; <- type error # proc foo[N] (x:array[int,N]) { x.[0] = 5; } <- type error Then, if we modified the "ref" reference to work like this: # proc foo[N] (ref x:array[int,N]) { x.[0] = 5; } # var x = 1,2,3; # foo x; # println x; -: (5, 2, 3) This then pretty much provides the "int*" and "const int* const" semantics. (I wonder if there's any way to achieve "const int*" or "int* const"...). This would also mean that we'd change the store (and all other mutation functions) to be written as: fun store[T,N]: ref array[T,N] * int * T And would allow us to use the pointer semantics for something else. Maybe OCaml-esque non-nullable reference types? Maybe we could write: # var x = ref 1,2,3; # *x = 4,5,6; # (*x).[0] = 0; <- type error That'd get "int* const". I'm not sure if that makes much sense though... ------------------------------------------------------------------------------ Crystal Reports - New Free Runtime and 30 Day Trial Check out the new simplified licensing option that enables unlimited royalty-free distribution of the report engine for externally facing server and web deployment. http://p.sf.net/sfu/businessobjects _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language