Why does xquery allow local variable redeclaration? - xquery

This will not even raise a warning:
xquery version "3.1";
let $a := 1
let $a := 2
return $a
(: yields 2 in all runtimes I tested :)
Why would a (functional) programming language allow variable re-declarations?
I really just want to get the rationale behind it.
By rejecting this at the compile step would enable some more aggressive optimisations, I believe.
Since local variables are also known to child scopes this just leaves more room for hard to catch errors.
JavaScript had this for years with var and finally got rid of it by introducing let and const.
Here is an example where it might be hard to track values.
xquery version "3.1";
let $f := function ($c) {
(: some code ... :)
let $b := $a
let $a := 2
let $c := $b
(: some more code ... :)
return ($a, $b, $c)
}
let $a := 1
return ($a, $f($a), $a)
You might want to guess first, before evaluating it.

"Why" questions are always difficult, because you can guess why the designers might have made the decisions they did, but it's usually not possible to get historical evidence of their reasoning. If you want research the history, the archives of the working group are available at https://lists.w3.org/Archives/Public/public-xsl-query/ -- but the search facilities are not particularly good, so you'll have your work cut out. But even if you find the relevant discussion in the minutes, it will probably only record the decision, and not the detailed arguments.
XSLT 1.0 didn't allow local variables to be re-declared, and I seem to recall that XSL people were generally against allowing it, while XQuery people were generally in favour. There are arguments both ways. The main argument for allowing it is probably the "no needless restrictions" argument: you don't disallow something if it has well-defined semantics. The argument for disallowing it was that people are likely to misuse and misunderstand it; they think that the two variables must somehow be related if they have the same name.
The Javascript analogy isn't a particularly good one, because variables in a procedural language are rather different from variables in a functional language.
Many other languages allow two local variables to have the same name provided they have different scope.

Related

Why are while loops predicated on typechecking (w/ tc_expr) the condition expression?

It seems that tc_expr is constrained to knowledge of the typing context and nothing else so it is not possible to safely "typecheck" an expression that requires knowledge of the heap state, e.g. a pointer dereference as the condition of a while loop. Why is that and would it ever be possible for me to prove correct a loop such as:
char *t = ...;
...
while (*t != 0)
{
...
t++;
}
I would think while loops could optionally be proven with a variation of tc_expr that does allow for pointer dereference by accounting for the heap context along with the typing context. I suspect that the thinking is that a loop condition should be a “pure” expression, but I’m ultimately curious if that is really a necessary constraint.
P.S. I realize that I could rewrite this as a for loop. My question still stands knowing that VST allows me to prove this kind of loop albeit with different syntax.
Answer number 1: It's a design decision, one way or the other, and we found that many things are simpler (and more in the spirit of Separation Logic) if expressions do not access memory.
Answer number 2: You can write this while loop, just as it is. Then use clightgen with the -normalize flag (which you should always use anyway), and then you can verify it. However, in such a case, the loop form will not be (strictly speaking) a Clight "while" loop, it will have it's loop-test (if (?) then /*skip*/; else break;) in the middle of the loop body; so you will use forward_loop to prove it, instead of forward_while.

Idiomatic alternative to reflection

I am trying to select a digest algorithm (from rust-crypto) based on a configuration string. In Python or JavaScript, say, I'd probably use reflection to get at this:
getattr(Digest, myAlgorithm)
...but from what I've been able to Google, this isn't best practice in a language such as Rust (plus I've found no details on how it could be done). My initial thought was to use a pattern match:
let mut digest = match myAlgorithm {
"sha256" => Sha256::new(),
...
};
However, this doesn't work because, while all the branches of the match implement the same trait, they're ultimately different types. Moreover, presuming there were a way around this, it's a lot of hassle to manually enumerate all these options in the code.
What's the right way to do this in Rust?
Since all the algorithms implement the same trait Digest, which offers everything you need, you can box all the algorithms and convert them to a common Box<Digest>:
let mut digest: Box<Digest> = match my_algorithm {
"sha256" => Box::new(Sha256::new()),
...
};
Now you don't know anymore what the type was, but you still know it's a Digest.
The python and javascript do the boxing (dynamic heap allocation) for you in the background. Rust is very picky about such things and therefor requires you to explicitly state what you mean.
It would be interesting to have reflection in Rust to be able to enumerate all types in scope that implement a trait, but such a system would require quite some effort in the rust compiler and in the brains of of the rust community members. Don't expect it any time soon.

if and elsif optimisation in Ada 95

I'm working on an Ada based project that I'm not terribly familiar with, and I've just seen something that at first glance seems inefficient, but of course that all depends on what the compiler might do.
if Ada.Strings.Fixed.Trim
(Source => Test_String,
Side => Ada.Strings.Both) =
String_1 then
--Do something here
elsif Ada.Strings.Fixed.Trim
(Source => Test_String,
Side => Ada.Strings.Both) =
String_2 then
--Do something else here
end if;
I feel that it would be more efficient to call the Trim procedure and store the result in a String variable, then test against different Strings in each condition of the if statement, especially if there are many conditions to check (never mind that using a binary search might be even better). Of course, I may be wrong, so my question is, is there something about compile time optimisation in Ada that I do not know about, that might cause the Trim function to only be called once, and only have the result tested in each condition of the if statement?
That would be compiler-dependent, not language-dependent. Certainly, GNAT GPL 2013 calls Trim twice both at -O2 and at -O3.
Your (and my) intuition seems to be right: do the trim once and store the result ...
Trimmed : constant String :=
Ada.Strings.Fixed.Trim (Source => Test_String, Side => Ada.Strings.Both);
... though personally I’d write
Trimmed : constant String :=
Ada.Strings.Fixed.Trim (Test_String, Side => Ada.Strings.Both);
on the grounds that in this case no one should need the named parameter association to clarify the programmer’s intention!
I don't think we need to worry about efficiency for this case. But the coding style that do need to be improved. To define a variable to hold the result of the Trim function is a better practice in my opinion. The program logic is clearer and easier for maintenance.
Let's say you want to change the Trim function to another one or change the parameter passing in, you only need to change one place. Although for this case there are only two places, you still have a chance to error. If there are more cases to test, then there definitely will be missing case.
While I have no disagreement whatsoever with your assessment or Simon's answer, it's worth bearing in mind what optimisation actually means...
If each call to "trim" takes (conservatively) 0.1ms of CPU time, and the rewrite takes 2 minutes, the breakeven point in time saved is over 1 million executions of that particular statement!
This of course ignores (a) on the positive side, the value of gaining experience, and (b) on the negative side, the fact that CPU time is nowadays less valuable than your time. And (c) the time we have spent discussing the optimisation too!
With respect to "compile time optimisation in Ada" , the Ada language doesn't say anything about this. All it would say here is that the program must behave as if the function were called twice, i.e. it must produce the same results. But if the compiler "knows" that the function would produce the exact same result the second time, it can generate code that calls it only once. It can't do this for a function call in general, because a function could include side effects or use global variables that whose values could have changed. In this case, since the effects of Ada.Strings.Fixed.Trim are defined by the language and since those effects do guarantee that the effects would be the same, a compiler could, in theory, mark this function as one for which a call with the exact same parameters could be optimized. (A function in a Pure package would definitely be one where a second call could be eliminated, but unfortunately Ada.Strings.Fixed isn't defined by the Ada language as being Pure.) To find out whether a compiler actually does this particular optimization, though, you'd have to try it and check the code. I believe that if Test_String is not marked as Volatile, then compilers are allowed to assume that its value will be the same for each Ada.Strings.Fixed.Trim call (i.e. it can't be changed by another task in between the calls), but I'm not 100% sure about this.
I'd declare a constant to hold the result (like Simon), but for me this is more out of a desire to avoid duplicated code than it is out of a concern for efficiency.

Real World Haskell book: don't understand the example

In Chapter 3, There is an example called "MySecond.hs", what I really don't understand is code like this:
safeSecond :: [a] -> Maybe a
it always in the first line of file, and delete it causes no trouble. anyone could enlight me with what that means? I am but a newbie to any functional programming language.
It is the type annotation. If you don't write it Haskell will infer it.
In this case safeSecond is the name of something. The :: separates the name from the type. It takes a list of type a(a is a type variable this function will work on a list of any type.) -> is function application, and Maybe a is the return type.
Note that 'a' represents a single type so if you pass in a int list you must get a Maybe int out. That is to say all 'a's in the the type must agree.
Maybe is just a type that has two alternatives Just a or Nothing.
It's the type signature of the function. It's meant to show what the inputs and outputs of the function are supposed/expected to be. For most Haskell code the compiler can infer it if you don't specify it, but it is highly recommended to always specify it.
Aside from helping you remember what the function should actually do, it's also a nice way for others to get an idea about what the function does.
Besides that, it's also useful for debugging, for instance when the type of the function isn't what you expected it to be. If you have a type signature for that function, you would get an error at the definition site of the function, vs if you don't you'd get one at the call site. see Type Signatures and Why use type signatures
Also since you're reading RWH, Chapter 2 covers this.
This is a type annotation; it acts like a function declaration in C.
In Haskell, type declaration is usually not strictly necessary, as Haskell can usually infer a good type from correct code. However, it is generally a good idea to declare types for important values, because:
If your code is not correct, you tend get more useful error messages that way (otherwise the compiler can get confused trying to infer your types, and the resulting failure message may not be clearly related to the actual error). If you are getting obscure/verbose error messages, adding type annotation may improve them.
Especially as a beginner, declaring important types can make you less confused about what you're doing -- it forces you to clarify your thinking as you write the program.
As others have mentioned, type annotation acts as active documentation, making other people less confused about your code. As usual, "other people" may be you, a few months down the road.

Can someone tell me what Strong typing and weak typing means and which one is better?

Can someone tell me what Strong typing and weak typing means and which one is better?
That'll be the theory answers taken care of, but the practice side seems to have been neglected...
Strong-typing means that you can't use one type of variable where another is expected (or have restrictions to doing so). Weak-typing means you can mix different types. In PHP for example, you can mix numbers and strings and PHP won't complain because it is a weakly-typed language.
$message = "You are visitor number ".$count;
If it was strongly typed, you'd have to convert $count from an integer to a string, usually with either with casting:
$message = "you are visitor number ".(string)$count;
...or a function:
$message = "you are visitor number ".strval($count);
As for which is better, that's subjective. Advocates of strong-typing will tell you that it will help you to avoid some bugs and/or errors and help communicate the purpose of a variable etc. They'll also tell you that advocates of weak-typing will call strong-typing "unnecessary language fluff that is rendered pointless by common sense", or something similar. As a card-carrying member of the weak-typing group, I'd have to say that they've got my number... but I have theirs too, and I can put it in a string :)
"Strong typing" and its opposite "weak typing" are rather weak in meaning, partly since the notion of what is considered to be "strong" can vary depending on whom you ask. E.g. C has been been called both "strongly typed" and "weakly typed" by different authors, it really depends on what you compare it to.
Generally a type system should be considered stronger if it can express the same constraints as another and more. Quite often two type systems are not be comparable, though -- one might have features the other lacks and vice versa. Any discussion of relative strengths is then up to personal taste.
Having a stronger type system means that either the compiler or the runtime will report more errors, which is usually a good thing, although it might come at the cost of having to provide more type information manually, which might be considered effort not worthwhile. I would claim "strong typing" is generally better, but you have to look at the cost.
It's also important to realize that "strongly typed" is often incorrectly used instead of "statically typed" or even "manifest typed". "Statically typed" means that there are type checks at compile-time, "manifest typed" means that the types are declared explicitly. Manifest-typing is probably the best known way of making a type system stronger (think Java), but you can add strength by other means such as type-inference.
I would like to reiterate that weak typing is not the same as dynamic typing.
This is a rather well written article on the subject and I would definitely recommend giving it a read if you are unsure about the differences between strong, weak, static and dynamic type systems. It details the differences much better than can be expected in a short answer, and has some very enlightening examples.
http://en.wikipedia.org/wiki/Type_system
Strong typing is the most common type model in modern programming languages. Those languages have one simple feature - knowing about type values in run time. We can say that strong typed languages prevent mixing operations between two or more different kind of types. Here is an example in Java:
String foo = "Hello, world!";
Object obj = foo;
String bar = (String) obj;
Date baz = (Date) obj; // This line will throw an error
The previous example will work perfectly well until program hit the last line of code where the ClassCastException is going to be thrown because Java is strong typed programming language.
When we talk about weak typed languages, Perl is one of them. The following example shows how Perl doesn't have any problems with mixing two different types.
$a = 10;
$b = "a";
$c = $a . $b;
print $c; # returns 10a
I hope you find this useful,
Thanks.
This article is a great read: http://blogs.perl.org/users/ovid/2010/08/what-to-know-before-debating-type-systems.html Cleared up a lot of things for me when researching trying to answer a similar question, hope others find it useful too.
Strong and Weak Typing:
Probably the most common way type systems are classified is "strong"
or "weak." This is unfortunate, since these words have nearly no
meaning at all. It is, to a limited extent, possible to compare two
languages with very similar type systems, and designate one as having
the stronger of those two systems. Beyond that, the words mean nothing
at all.
Static and Dynamic Types
This is very nearly the only common classification of type systems
that has real meaning. As a matter of fact, it's significance is
frequently under-estimated [...] Dynamic and static type systems are
two completely different things, whose goals happen to partially
overlap.
A static type system is a mechanism by which a compiler examines
source code and assigns labels (called "types") to pieces of the
syntax, and then uses them to infer something about the program's
behavior. A dynamic type system is a mechanism by which a compiler
generates code to keep track of the sort of data (coincidentally, also
called its "type") used by the program. The use of the same word
"type" in each of these two systems is, of course, not really entirely
coincidental; yet it is best understood as having a sort of weak
historical significance. Great confusion results from trying to find a
world view in which "type" really means the same thing in both
systems. It doesn't.
Explicit/Implicit Types:
When these terms are used, they refer to the extent to which a
compiler will reason about the static types of parts of a program. All
programming languages have some form of reasoning about types. Some
have more than others. ML and Haskell have implicit types, in that no
(or very few, depending on the language and extensions in use) type
declarations are needed. Java and Ada have very explicit types, and
one is constantly declaring the types of things. All of the above have
(relatively, compared to C and C++, for example) strong static type
systems.
Strong/weak typing in a language is related to how easily you can do type conversions:
For example in Python:
str = 5 + 'a'
# would throw an error since it does not want to cast one type to the other implicitly.
Where as in C language:
int a = 5;
a = 5 + 'c';
/* is fine, because C treats 'c' as an integer in this case */
Thus Python is more strongly typed than C (from this perspective).
May be this can help you to understand Strong and Weak Typing.......
Strong typing: It checks the type of variables as soon as possible, usually at compile time. It prevents mixing operations between mismatched types.
A strong-typed programming language is one in which:
All variables (or data types) are known at compile time
There is strict enforcement of typing rules (a String can't be used
where an Integer would be expected)
All exceptions to typing rules results in a compile time error
Weak Typing: While weak typing is delaying checking the types of the system as late as possible, usually to run-time. In this you can mix types without an explicit conversion.
A "weak-typed" programming language is simply one which is not strong-typed.
which is preferred depends on what you want. for scripts and good stuff you will usually want weak typing, because you want to write as much less code as possible. in big programs, strong typing can reduce errors at compile time.
Weak typing means that you don't specify what type a variable is, and strong typing means you give a strict type to each variable.
Each has its advantages, with weak typing (or dynamic typing, as it is often called), being more flexible and requiring less code from the programmer. Strong typing, on the other hand, requires more work from the developer, but in return it can alert you of many mistakes when compiling your code, before you run it. Dynamic typing may delay the discovery of these simple problems until the code is executed.
Depending on the task at hand, weak typing may be better than strong typing, or vice versa, but it is mostly a matter of taste. Weak typing is commonly used in scripting languages, while strong typing is used in most compiled languages.

Resources