convertion between record and tuple? - sml

Now that tuple is just record in SML, I tried:
The codes above I hope this record can accept a tuple, but it reports an error.
So, there's no implicit conversion from tuple to record and from record to tuple(though didn't post here, I have tried at local actually).
My question is why SML doesn't supply such conversion?(because these conversions are quite frequent in c++)

Tuples are records with members named 1 through n. That is, the three element tuple (a, b, c) is really a record {1 = a, 2 = b, 3 = c}. So there doesn't need to be an implicit conversion between tuples and records because they're already the same thing.
Now the function you defined takes a record with the members x, y and z and you pass it a record with the members 1, 2 and 3. This doesn't work. For this to work there'd need to be an implicit conversion between records with different member names, which seems like a very bad idea.
(because these conversions are quite frequent in c++)
There are no implicit conversions in C++ between unrelated structs or classes with different members (or even the same members). To do that, you'd need a reinterpret_cast (or a C-style pointer cast on the address), which is neither common nor a good idea (and wouldn't work with anything but POD types).

Related

How to look up an object by name in Fortran [duplicate]

I want to create a dynamic variable name using Fortran.
The variable name will be obtained by concatenating a string and another string/integer. Then I want to use this variable name to store a value or another variable.
e.g.
! assign values to 2 variables
my_string = h
my_integer = 1
! perform concatenation resulting in the dynamic variable name, h1
! Set the value of variable h1 to another integer value
h1 = 5
I fear that you will not be able to do this. Fortran requires that variables have names and types at compile time. You (or other SOers) may come up with some kludge to simulate what you want, but it will be a kludge.
Why do you want to do this in Fortran ? There are plenty of languages around which do permit this sort of variable declaration.
EDIT
Well, I thought about it some more, and here's a kludge, unfinished. First a UDT for 'dynamic' variables:
type dynamic_var
character(len=:), allocatable :: label
class(*), allocatable :: value
end type
declare some space for such variables:
type(dynamic_var), dimension(:), allocatable :: run_time_vars
and, working with your original data
allocate(run_time_vars(10)) ! No error checking, reallocate if necessary
! lots of code
write(run_time_vars(1)%label,'(a1,i1)') my_string, my_integer
allocate(run_time_vars(1)%value, source = my_value)
This compiles, but doesn't run and I'm not going to stay long enough to fix it, I'll leave that as an exercise to anyone who cares.
The write to the label field isn't right.
The sourced allocation to the value field doesn't seem to work correctly. Might need to write a 'decode' function to use like this:
allocate(run_time_vars(1)%value, source = decode(my_value))
Like I said, it's a kludge.
I think you want to use a data structure. If you have pairs or groups of values that go together, then create a derived data type which can hold both. There's an explanation on this page:
http://web.mse.uiuc.edu/courses/mse485/comp_info/derived.html
If you have a list of these pairs (like your string and int above), then you can create an array of these types. Example code below taken from the page linked above:
type mytype
integer:: i
real*8 :: a(3)
end type mytype
type (mytype) var
Array:
type (mytype) stuff(3)
var%i = 3
var%a(1) = 4.0d0
stuff(1)%a(2) = 8.0d0
An significant benefit of doing this is that you can pass the pairs/groups of items to functions/subroutines together. This is an important programming principle called Encapsulation, and is used extensively in the Object Oriented programming paradigm.
No, this is not possible in Fortran.
For more information, look into Reflection (computer programming).
Clearly, for reasons given above, this is not legit Fortran (and thus you're going into trouble ...). You may use smart (congrats guys!) kludges, but ...
Instead of using variables h concatenated with 1, 2 or whatever number, why not creating array h(1:N) where N does not have to be known at compilation time : you just have to declare array h as a allocatable.
This is, I think, the legit way in Fortran 90+.

Tuple Concatenation in Chapel

Let's say I'm generating tuples and I want to concatenate them as they come. How do I do this? The following does element-wise addition:
if ts = ("foo", "cat"), t = ("bar", "dog")
ts += t gives ts = ("foobar", "catdog"),
but what I really want is ts = (("foo","cat"),("bar","dog")).
So I guess the first question is "does Chapel support tuple concatention?", then "is there a binary operator/function for it?", then "if not, what is a good way to do it?", and lastly "make my life easier if you know a better way of living".
Please address the questions in order.
I appreciate the help!!
the first question is "does Chapel support tuple concatention?"
I believe the answer here is "no" for the following reason: (1) A Chapel variable has a single static type that cannot change over its lifetime, and (2) a tuple's type is defined as its static number of elements as well as the type of each element. Thus, given your variable ts
ts = ("foo", "cat")
its type is 2*string ("a 2-tuple of strings") and this would prevent it from ever being able to store the value (("foo","cat"),("bar","dog")) since its type is 2*(2*string) ("a 2-tuple of 2-tuples of strings"). So while these two tuples have the same number of elements (2), they differ in their element types ("string" vs. "2-tuple of string") and therefore aren't the same type (aren't compatible).
"is there a binary operator/function for it?"
Due to the above, no.
then "if not, what is a good way to do it?"
A few things come to mind, but may or may not be helpful depending on your specific situation. Rather than trying to re-assign ts, you could create a new tuple that was a tuple-of-tuples:
const ts2 = (ts, t);
and you could even do this recursively in a routine, though that would likely end up blowing up your code size if the tuple grew to any significant length (because each call to the function would generate a tuple of a different type and unique code for it).
From what I'm seeing in your question, I think you may want to use a list of tuples or a 1D array (vector) of tuples. Here's a list-based approach:
use List;
var listOfTups: list(2*string);
listOfTups.append(("foo", "cat"));
listOfTups.append(("bar", "dog"));
writeln(listOfTups);
And here's an array-based approach:
var arrOfTups: [1..0] 2*string;
arrOfTups.push_back(("foo", "cat"));
arrOfTups.push_back(("bar", "dog"));
writeln(arrOfTups);
Of the two, I would recommend the array-based approach because arrays are much more first-class and powerful in Chapel (they enjoy syntactic support, permit data parallelism, support promotion of scalar functions and operators, etc.) whereas lists are just a convenience library.
and lastly "make my life easier if you know a better way of living".
One other related thing I can think of to mention if you're not aware of it is that "varargs" functions in Chapel effectively convert those arguments to tuples. So given:
proc myFunc(x...) {
writeln(x.type:string);
}
myFunc(("foo", "cat"), ("bar", "dog"));
the output is:
2*2*string

Haskell - Tuples and Lists as built-in types: how are they actually declared?

In chapter 2 of "A gentle introduction to Haskell", user-defined types are explained and then the notion that built-in types are, apart from a special syntax, no more different than user-defined ones:
Earlier we introduced several "built-in" types such as lists, tuples, integers, and characters. We have also shown how new user-defined types can be defined. Aside from special syntax, are the built-in types in any way more special than the user-defined ones? The answer is no. (The special syntax is for convenience and for consistency with historical convention, but has no semantic consequences.)
So you could define a tuple like to the following:
data (a,b) = (a,b)
data (a,b,c) = (a,b,c)
data (a,b,c,d) = (a,b,c,d)
Which sure you cannot because that would require an infinite number of declarations. So how are these types actually implemented? Especially regarding the fact that only against a type declaration you can pattern-match?
Since GHC is open source, we can just look at it:
The tuples are a lot less magical than you think:
From https://github.com/ghc/ghc/blob/master/libraries/ghc-prim/GHC/Tuple.hs
data (a,b) = (a,b)
data (a,b,c) = (a,b,c)
data (a,b,c,d) = (a,b,c,d)
data (a,b,c,d,e) = (a,b,c,d,e)
data (a,b,c,d,e,f) = (a,b,c,d,e,f)
data (a,b,c,d,e,f,g) = (a,b,c,d,e,f,g)
-- and so on...
So, tuples with different arities are just different data types, and tuples with very big number of arities is not supported.
Lists are also around there:
From https://github.com/ghc/ghc/blob/master/libraries/ghc-prim/GHC/Types.hs#L101
data [] a = [] | a : [a]
But there is a little bit of magic (special syntax) for lists.
Note: I know that GitHub is not where GHC is developed, but searching "ghc source code" on Google did not yield the correct page, and GitHub was the easiest.
You defined three tuple types there, not one hence your argument with the infinite number of declarations doesn't cut. A standard confoming Haskell needs to support only a finite number of tuple types. Hence finitely many declarations.
In fact, you can define:
data Pair a b = Pair a b
and this is isomorphic to an ordinary 2-tuple.

What's the OCaml naming convention for "constructors"?

An OCaml module usually contains at least one abstract type whose idiomatic name is t. Also, there's usually a function that constructs a value of that type.
What is the usual / idiomatic name for this?
The StdLib is not consistent here. For example:
There's Array.make and a deprecated function Array.create. So that function should be named make?
On the other hand, there's Buffer.create but not Buffer.make. So that function should be named create?
Some people find this way of module design makes OCaml programming easier, but this is not a mandatory OCaml programming style, and I do not think there is no official name for it. I personally call it "1-data-type-per-1-module" style. (I wrote a blog post about this but it is in Japanese. I hope some autotranslator gives some useful information to you ...)
Defining a module dedicated to one data type and fix the name of the type t has some values:
Nice namespacing
Module names explain about what its type and values are, therefore you do not need to repeat type names inside: Buffer.add_string instead of add_string_to_buffer, and Buffer.create instead of create_buffer. You can also avoid typing the same module names with local module open:
let f () =
let open Buffer in
let b = create 10 in (* instead of Buffer.create *)
add_string b "hello"; (* instead of Buffer.add_string *)
contents b (* instead of Buffer.contents *)
Easy ML functor application
If an ML functor takes an argument module with a data type, we have a convention that the type should be called t. Modules with data type t are easily applied to these functors without renaming of the type.
For Array.create and Array.make, I think this is to follow the distinction of String.create and String.make.
String.create is to create a string with uninitialized contents. The created string contains random bytes.
String.make is to create a string filled with the given char.
We had Array.create for long, to create an array whose contents are filled with the given value. This behavior corresponds with String.make rather than String.create. That's why it is now renamed to Array.make, and Array.create is obsolete.
We cannot have Array.create in OCaml with the same behaviour of String.create. Unlike strings, arrays cannot be created without initialization, since random bytes may not represent a valid OCaml value for the content in general, which leads to a program crash.
Following this, personally I use X.create for a function to create an X.t which does not require an initial value to fill it. I use X.make if it needs something to fill.
I had the same question when I picked up the language a long time ago. I never use make and I think few people do.
Nowadays I use create for heavy, often imperative or stateful values, e.g. a Unicode text segmenter. And I use v for, functional, lighter values in DSL/combinator based settings, e.g. the various constructors in Gg, for example for 2D vectors, or colors.
As camlspotter mentions in his answer the standard library distinguishes make and create for values that need an initial value to fill in. I think it's better to be regular here and always use create regardless. If your values support an optional initial fill value, add an optional argument to create rather than multiply the API entry points.

What's the difference between records and tuples in OCaml

Is there any difference between records and tuples that is not just a syntactic difference ?
Is there a performance difference ?
Is the implementation the same for tuples and records ?
Do you have examples of things that can be done using tuples but not with records (and
conversely) ?
Modulo syntax they are almost the same. The main semantic difference is that tuples are structural types, while records are nominal types. That implies e.g. that records can be recursive while tuples cannot (at least not without the -rectypes option):
type t = {a : int, b : unit -> t} (* fine *)
type u = int * (unit -> u) (* error *)
Moreover, records can have mutable fields, tuples can't.
FWIW, in OCaml's sister language SML, tuples are records. That is, in SML (a,b,c) is just syntactic sugar for {1=a,2=b,3=c}, and records are structural types as well.
Floats fields in float-only records or arrays are stored unboxed, while no such optimization applies to tuples. If you are storing a lot of floats and only floats, it is important to use records -- and you can gain by splitting a mixed float/other datastructure to have an internal float-only record.
The other differences are at the type level, and were already described by Andreas -- records are generative while tuples pre-exist and have a structural semantics. If you want structural records with polymorphic accessors, you can use object types.