Related
We would like to exchange PO files with translators, and convert these to i18next's native JSON format. This sounds pretty straightforward using the i18next-conv utility.
However, i18next expects more or less special keys; for example the dot has special meaning with regard to i18next namespaces. In contrast, gettext PO files are intended to carry source strings (in the original language) for their message IDs.
We know that message IDs can be arbitrary, and can thus be mapped to i18next keys directly, but we would like to use source strings and use PO files as they were intended for various reasons.
The main reason is that all the translation tools we would like to use, and probably those of all our translators, expect this. Using symbolic keys would make translating a real pain. In any case, we figured from the debates around this that this is mainly a matter of opinion; we kind of made ours, and we would like to put this restriction as a requirement for this question.
Is it really a bad idea to use source strings as i18next keys from a technical standpoint? How hard is it to escape them? Is there anything else than the dot and namespaces that we should care about?
If we determine that we want to keep using symbolic keys, is there an alternative to i18next-conv that can generate i18next JSON translation files from PO files using source strings as message IDs? We understand that we would most likely need to maintain a separate mapping between the symbolic names and the original language strings, and we're prepared to do so.
Moreover, we wonder about the general workflow. How is the original PO file generated? How are the translation files maintained?
If we use source strings as keys in i18next, what are the best tools to extract strings from the codebase? xgettext doesn't seem to support Javascript.
If we use symbolic keys in i18next, how can we best generate the original PO file? Is writing a POT file by hand a good practice?
Again, if we use symbolic keys, how can we easily invalidate translations whenever we update the original language strings? Are there tools for that?
We understand these questions are very basic, but we were a bit surprised at how little information we could find about i18next-gettext integration. The i18next-conv tool exists and works perfectly as advertised, but is it actually useful? Do people actually use it? If so, are our questions relevant?
Finally, are our expectations about the maturity of the system a little too high?
if you like to use source strings as keys just change the
nsseparator = ':::'
keyseparator = '::'
so . and : could be used inside the key without fear.
You could try using https://github.com/cheton/i18next-text. It allows you using i18next translation without having the key as strings, and you do not need to worry about i18n key naming. Furthermore, you can also register the i18n helper with Handlebars.
Following is a simple example:
var i18n = require('i18next');
// extends i18n object to provide a new _() method
i18n._ = require('i18next-text')._;
i18n._('Save your time and work more efficiently.');
Check out the demo on JSFiddle.
I'm reading a slide deck that states "JavaScript is untyped." This contradicted what I thought to be true so I started digging to try and learn more.
Every answer to Is JavaScript an untyped language? says that JavaScript is not untyped and offered examples of various forms of static, dynamic, strong, and weak typing that I'm familiar and happy with.. so that wasn't the way to go.
So I asked Brendan Eich, the creator of JavaScript, and he said:
academic types use "untyped" to mean "no static types". they are smart enough to see that values have types (duh!). context matters.
Do academically-focused computer science folks use "untyped" as a synonym of "dynamically typed" (and is this valid?) or is there something deeper to this that I am missing? I agree with Brendan that context is important but any citations of explanations would be great as my current "go to" books are not playing ball on this topic.
I want to nail this down so I can improve my understanding and because even Wikipedia doesn't refer to this alternative usage (that I can find, anyway). I don't want to mess up with either using the term or questioning the use of the term in future if I'm wrong :-)
(I've also seen a top Smalltalker say Smalltalk is "untyped" too, so it's not a one-off which is what set me off on this quest! :-))
Yes, this is standard practice in academic literature. To understand it, it helps to know that the notion of "type" was invented in the 1930s, in the context of lambda calculus (in fact, even earlier, in the context of set theory). Since then, a whole branch of computational logic has emerged that is known as "type theory". Programming language theory is based on these foundations. And in all these mathematical contexts, "type" has a particular, well-established meaning.
The terminology "dynamic typing" was invented much later -- and it is a contradiction in terms in the face of the common mathematical use of the word "type".
For example, here is the definition of "type system" that Benjamin Pierce uses in his standard text book Types and Programming Languages:
A type system is a tractable syntactic method for proving the absence
of certain program behaviors by classifying phrases according to the
kinds of values they compute.
He also remarks:
The word “static” is sometimes added explicitly--we speak of a
“statically typed programming language,” for example--to distinguish the
sorts of compile-time analyses we are considering here from the
dynamic or latent typing found in languages such as Scheme (Sussman
and Steele, 1975; Kelsey, Clinger, and Rees, 1998; Dybvig, 1996),
where run-time type tags are used to distinguish different kinds of
structures in the heap. Terms like “dynamically typed” are arguably
misnomers and should probably be replaced by “dynamically checked,”
but the usage is standard.
Most people working in the field seem to be sharing this point of view.
Note that this does not mean that "untyped" and "dynamically typed" are synonyms. Rather, that the latter is a (technically misleading) name for a particular case of the former.
PS: And FWIW, I happen to be both an academic researcher in type systems, and a non-academic implementer of JavaScript, so I have to live with the schisma. :)
I am an academic computer scientist specializing in programming languages, and yes, the word "untyped" is frequently (mis)-used in this way. It would be nice to reserve the word for use with languages that don't carry dynamic type tags, such as Forth and assembly code, but these languages are rarely used and even more rarely studied, and it's a lot easier to say "untyped" than "dynamically typed".
Bob Harper is fond of saying that languages like Scheme, Javascript, and so on should be considered typed languages with just a single type: value. I lean to this view, as it makes it possible to construct a consistent worldview using just one type formalism.
P.S. In pure lambda calculus, the only "values" are terms in normal form, and the only closed terms in normal form are functions. But most scientists who use the lambda calculus add base types and constants, and then you either include a static type system for lambda or you are right back to dynamic type tags.
P.P.S. To original poster: when it comes to programming languages, and especially type systems, the information on Wikipedia is of poor quality. Don't trust it.
I've looked into it, and found that the answer to your question is simply, and surprisingly, "yes": academic CS types, or at least some of them, do use "untyped" to mean "dynamically typed". For example, Programming Languages: Principles and Practices, Third Edition (by Kenneth C. Louden and Kenneth A. Lambert, published 2012) says this:
Languages without static type systems are usually called untyped languages (or dynamically typed languages). Such languages include Scheme and other dialects of Lisp, Smalltalk, and most scripting languages such as Perl, Python, and Ruby. Note, however, that an untyped language does not necessarily allow programs to corrupt data—this just means that all safety checking is performed at execution time. […]
[link] (note: bolding in original) and goes on to use "untyped" in just this way.
I find this surprising (for much the same reasons that afrischke and Adam Mihalcin give), but there you are. :-)
Edited to add: You can find more examples by plugging "untyped languages" into Google Book Search. For example:
[…] This is the primary information-hiding mechanism is many untyped languages. For instance PLT Scheme [4] uses generative structs, […]
— Jacob Matthews and Amal Ahmed, 2008 [link]
[…], we present a binding-time analysis for an untyped functional language […]. […] It has been implemented and is used in a partial evaluator for a side-effect free dialect of Scheme. The analysis is general enough, however, to be valid for non-strict typed functional languages such as Haskell. […]
— Charles Consel, 1990 [link]
By the way, my impression, after looking through these search results, is that if a researcher writes of an "untyped" functional language, (s)he very likely does consider it to be "untyped" in the same sense as the untyped lambda calculus that Adam Mihalcin mentions. At least, several researchers mention Scheme and the lambda calculus in the same breath.
What the search doesn't say, of course, is whether there are researchers who reject this identification, and don't consider these languages to be "untyped". Well, I did find this:
I then realized that there is really no circularity, because dynamically typed languages are not untyped languages — it's just that the types are not usually immediately obvious from the program text.
— someone (I can't tell who), 1998 [link]
but obviously most people who reject this identification wouldn't feel a need to explicitly say so.
Untyped and dynamically typed are absolutely not synonyms. The language that is most often called "untyped" is the Lambda Calculus, which is actually a unityped language - everything is a function, so we can statically prove that the type of everything is the function. A dynamically typed language has multiple types, but does not add a way for the compiler to statically check them, forcing the compiler to insert runtime checks on variable types.
Then, JavaScript is a dynamically typed language: it is possible to write programs in JavaScript such that some variable x could be a number, or a function, or a string, or something else (and determining which one would require solving the Halting Problem or some hard mathematical problem), so you can apply x to an argument and the browser has to check at runtime that x is a function.
Both statements are correct, depending on whether you are talking about values or variables. JavaScript variables are untyped, JavaScript values have types, and variables can range over any value type at runtime (i.e. 'dynamically').
In JavaScript and many other languages, values and not variables carry types. All variables can range over all types of values and may be considered "dynamically typed" or "untyped" - from the perspective of type-checking a variable that has no/unknowable type and a variable that can take any type are logically and practically equivalent. When type theorists talk about languages and types, they are usually talking about this - variables carrying types - because they are interested in writing type checkers and compilers and so on, which operate on program text (i.e. variables) and not a running program in memory (i.e. values).
By contrast in other languages, like C, variables carry types but values do not. In languages like Java, variables and values both carry types. In C++, some values (those with virtual functions) carry types and others do not. In some languages it is even possible for values to change types, although this is usually considered bad design.
While it is true that most of the CS researchers that write about types essentially consider only languages with syntactically-derivable types as typed languages, there are lots more of us using dynamically/latently typed languages who take umbrage at that usage.
I consider there to be 3 types [SIC] of languages:
Untyped - only the operator determines the interpretation of the value - and it generally works on anything. Examples: Assembler, BCPL
Statically typed - expressions/variables have types associated with them, and that type determines the interpretation/validity of the operator at compile-time. Examples: C, Java, C++, ML, Haskell
Dynamically typed - values have types associated with them, and that type determines the interpretation/validity of the operator at run-time. Examples: LISP, Scheme, Smalltalk, Ruby, Python, Javascript
To my knowledge, all dynamically-typed languages are type-safe - i.e. only valid operators can operate on values. But the same is not true for statically-typed language. Depending on the power of the type system used, some operators may be checked only at run-time, or not at all. For example, most statically-typed languages do not handle integer overflow properly (adding 2 positive integers can produce a negative integer), and out-of-bound array references are either not checked at all (C, C++) or are checked only at run-time. Further, some type systems are so weak that useful programming requires escape hatches (casts in C and family) to change the compile-time type of expressions.
All of this leads to absurd claims, such as that C++ is safer than Python because it's (statically-typed), whereas the truth is that Python is intrinsically safe while you can shoot your leg off with C++.
This question is all about Semantics
If I give you this data: 12 what is it's type? You have no way of knowing for sure. Could be an integer - could be a float - could be a string. In that sense it's very much "untyped" data.
If I give you an imaginary language which lets you use operators like "add", "subtract", and "concatenate" on this data and some other arbitrary piece of data the "type" is somewhat irrelevant (to my imaginary language) (example: perhaps add(12, a) yields 109 which is 12 plus the ascii value of a).
Let's talk C for a second. C pretty much lets you do whatever you want with any arbitrary piece of data. If you're using a function that takes two uints - you could cast and pass anything you want - and the values will simply be interpreted as uints. In that sense C is "untyped" (if you treat it in such a way).
However - and getting to Brendan's point - if I told you that "My age is 12" - then 12 has a type - at least we know it's numeric. With context everything has a type - regardless of the language.
This is why I said at the beginning - your question is one of semantics. What is the meaning of "untyped"? I think Brendan hit the nail on the head when he said "no static types" - because that's all it can possibly mean. Humans naturally classify things into types. We intuitively know that there is something fundamentally different between a car and a monkey - without ever being taught to make those distinctions.
Getting back to my example in the beginning - a language that "doesn't care about types" (per-se) may let you "add" an "age" and a "name" without producing a syntax error... but that doesn't mean it's a logically sound operation.
Javascript may let you do all sorts of crazy things without considering them "errors". That doesn't mean what you are doing is logically sound. Thats for the developer to work out.
Is a system/language which doesn't enforce type safety at compile/build/interpretation time "untyped" or "dynamically typed"?
Semantics.
EDIT
I wanted to add something here because some people seem to be getting caught up on "yeah, but Javascript does have some "types"".
In my comment on someone else's answer I said:
In Javascript I could have objects I've built up to be "Monkeys" and objects I've built up to be "Humans" and some functions could be designed to operate on only "Humans", others on only "Monkeys", and yet others on only "Things With Arms". Whether or not the language has ever been told there is such a category of objects as "things with arms" is as irrelevant to assembly ("untyped") as it is to Javascript ("dynamic"). It's all a matter of logical integrity - and the only error would be using something that didn't have arms with that method.
So, if you consider Javascript to have some "notion of types" internally - and, hence "dynamic types" - and think this is somehow "distinctly different from an untyped system" - you should see from the above example that any "notion of types" it has internally is really irrelevant.
To perform the same operation with C#, for example, I'd NEED an interface called ICreatureWithArms or something similar. Not so in Javascript - not so in C or ASM.
Clearly, whether or not Javascript has any understanding of "types" at all is irrelevant.
I am not a computer scientist, but I would be rather surprised if "untyped" were really used as a synonym for "dynamically typed" in the CS community (at least in scientific publications) as imho those two terms describe different concepts. A dynamically typed language has a notion of types and it enforces the type constraints at runtime (you can't for example divide an integer by a string in Lisp without getting an error) while an untyped language doesn't have any notion of types at all (e.g. assembler). Even the Wikipedia article about programming languages (http://en.m.wikipedia.org/wiki/Programming_language#Typed_versus_untyped_languages) makes this distinction.
Update: Maybe the confusion comes from the fact that some texts say something to the extent that "variables are not typed" in Javascript (which is true). But that doesn't automatically mean that the language is untyped (which would be false).
Agree with Brendan - context is everything.
My take:
I remember being confused, circa 2004, because there were arguments breaking out about whether Ruby was untyped or dynamically typed. Old school C/C++ people (of which I was one) were thinking about the compiler and saying Ruby was untyped.
Remember, in C, there are no runtime types, there are just addresses and if the code that's executing decides to treat whatever's at that address as something it isn't, whoops. That's definitely untyped and very different from dynamically typed.
In that world, "typing" is all about the compiler. C++ had "strong typing" because the compiler's checks were more stringent. Java and C were more "weakly typed" (there were even arguments about whether Java was strongly or weakly typed). Dynamic languages were, in that continuum, "untyped" because they had no compiler type checking.
Today, for practicing programmers, we're so used to dynamic languages, we obviously think of untyped to mean no compiler nor interpreter type-checking, which would be insanely hard to debug. But there was a period there where that wasn't obvious and in the more theoretical world of CS is may not even be meaningful.
In some deep sense, nothing can be untyped (or almost nothing, anyway) because you must have some intent in manipulating a value to write a meaningful algorithm. This is the world of theoretical CS, which isn't dealing with the specifics of how a compiler or interpreter is implemented for a given language. So "untyped" is (probably, I don't know) entirely meaningless in that context.
A friend of mine drew my attention the welcome message of 4th European Lisp Symposium:
... implementation and application of
any of the Lisp dialects, including
Common Lisp, Scheme, Emacs Lisp,
AutoLisp, ISLISP, Dylan, Clojure,
ACL2, ECMAScript, ...
and then asked if ECMAScript is really a dialect of Lisp. Can it really be considered so? Why?
Is there a well defined and clear-cut set of criteria to help us detect whether a language is a dialect of Lisp? Or is being a dialect taken in a very loose sense (and in that case can we add Python, Perl, Haskell, etc. to the list of Lisp dialects?)
Brendan Eich wanted to do a Scheme-like language for Netscape, but reality intervened and he ended up having to make do with something that looked vaguely like C and Java for "normal" people, but which worked like a functional language.
Personally I think it's an unnecessary stretch to call ECMAScript "Lisp", but to each his own. The key thing about a real Lisp seems like the characteristic that data structure notation and code notation are the same, and that's not true about ECMAScript (or Ruby or Python or any other dynamic functional language that's not Lisp).
Caveat: I have no Lisp credentials :-)
It's not. It's got a lot of functional roots, but so do plenty of other non-lisp languages nowadays, as you pointed out.
Lisps have one remaining characteristic that make them lisps, which is that lisp code is written in terms of lisp data structures (homoiconicity). This is what enables lisps powerful macro system, and why it looks so bizzare to non-lispers. A function call is just a list, where the first element in the list is the name of the function.
Since lisp code is just lisp data, it's possible to do some extremely powerful stuff with metaprogramming, that just can't be done in other languages. Many lisps, even modern ones like clojure, are largely implemented in themselves as a set of macros.
Even though I wouldn't call JavaScript a Lisp, it is, in my humble opinion, more akin to the Lisp way of doing things than most mainstream languages (even functional ones).
For one, just like Lisp, it's, in essence, a simple, imperative language based on the untyped lambda calculus that is fit to be driven by a REPL.
Second, it's easy to embed literal data (including code in the form of lambda expressions) in JavaScript, since a subset of it is equivalent to JSON. This is a common Lisp pattern.
Third, its model of values and types is very lispy. It's object-oriented in a broad sense of the word in that all values have a concept of identity, but it's not particularly object-oriented in most narrower senses of the word. Just as in Lisp, objects are typed and very dynamic. Code is usually split into units of functions, not classes.
In fact, there are a couple of (more or less) recent developments in the JavaScript world that make the language feel pretty lispy at times. Take jQuery, for example. Embedding CSS selectors as a sublanguage is a pretty Lisp-like approach, in my opinion. Or consider ECMAScript Harmony's metaobject protocol: It really looks like a direct port of Common Lisp's (much more so than either Python's or Ruby's metaobject systems!). The list goes on.
JavaScript does lack macros and a sensible implementation of a REPL with editor integration, which is unfortunate. Certainly, influences from other languages are very much visible as well (and not necessarily in a bad way). Still, there is a significant amount of cultural compatibility between the Lisp and JavaScript camps. Some of it may be coincidental (like the recent rise of JavaScript JIT compilation), some systematic, but it's definitely there.
If you call ECMAScript Lisp, you're basically asserting that any dynamic language is Lisp. Since we already have "dynamic language", you're reducing "Lisp" to a useless synonym for it instead of allowing it to have a more specific meaning.
Lisp should properly refer to a language with certain attributes.
A language is Lisp if:
Its source code is tree-structured data, which has a straightforward printed notation as nested lists. Every possible tree structure has a rendering in the corresponding notation and is susceptible to being given a meaning as a construct; the notation itself doesn't have to be extended to extend the language.
The tree-structured data is a principal data structure in the language itself, which makes programs susceptible to manipulation by programs.
The language has symbol data type. Symbols have a printed representation which is interned: when two or more instances of the same printed notation for a symbol appear in the notation, they all denote the same object.
A symbol object's principal virtue is that it is different from all other symbols. Symbols are paired with various other entities in various ways in the semantics of Lisp programs, and thereby serve as names for those entities.
For instance, dialect of Lisp typically have variables, just like other languages. In Lisp, variables are denoted by symbols (the objects in memory) rather than textual names. When part of a Lisp program defines some variable a, the syntax for that a is a symbol object and not the character string "a", which is just that symbol's name for the purposes of printing. A reference to the variable, the expression written as a elsewhere in the program, is also an on object. Because of the way symbols work, it is the same object; this object sameness then connects the reference to the definition. Object sameness might be implemented as pointer equality at the machine level. We know that two symbol values are the same because they are pointers to the same memory location in the heap (an object of symbol type).
Case in point: the NewLisp dialect which has a non-traditional memory management for most data types, including nested lists, makes an exception for symbols by making them behave in the above way. Without this, it wouldn't be Lisp. Quote: "Objects in newLISP (excluding symbols and contexts) are passed by value copy to other user-defined functions. As a result, each newLISP object only requires one reference." [emphasis mine]. Passing symbols too, as by value copy, would destroy their identity: a function receiving a symbol wouldn't be getting the original one, and therefore not correctly receiving its identity.
Compound expressions in a Lisp language—those which are not simple primaries like numbers or strings—consist of a simple list, whose first element is a symbol indicating the operation. The remaining elements, if any, are argument expressions. The Lisp dialect applies some sort of evaluation strategy to reduce the expression to a value, and evoke any side effects it may have.
I would tentatively argue that lists being made of binary cells that hold pairs of values, terminated by a special empty list object, probably should be considered part of the definition of Lisp: the whole business of being able to make a new list out of an existing one by "consing" a new item to the front, and the easy recursion on the "first" and "rest" of a list, and so on.
And then I would stop right there. Some people believe that Lisp systems have to be interactive: provide an environment with a listener, in which everything is mutable, and can be redefined at any time and so on. Some believe that Lisps have to have first-class functions: that there has to be a lambda operator and so on. Staunch traditionalists might even insists that there have to be car and cdr functions, the dotted pair notation supporting improper lists, and that lists have to be made up of cells, and terminated by specifically the symbol nil denoting the empty list, and also a Boolean false. Insisting on car and cdr allows Scheme to be a Lisp, but nil being the list terminator and false rules
The more we shovel into the definition of "Lisp dialect", though, the more it becomes political; people get upset that their favorite dialect (perhaps which they created themselves) is being excluded on some technicality. Insisting on car and cdr allows Scheme to be a Lisp, but nil being the list terminator and false rules it out. What, Scheme not a Lisp?
So, based on the above, ECMAScript isn't a dialect of Lisp. However, an ECMAScript implementation contains functionality which can be exposed as a Lisp dialect and numerous such dialects have been developed. Someone who needs wants ECMAScript to be considered a Lisp for some emotional reasons should perhaps be content with that: that the semantics to support Lisp is there, and just needs a suitable interface to that semantics, which can be developed in ECMAScript and which can interoperate with ECMAScript code.
No it's not.
In order to be considered a Lisp, one has to be homoiconic, which ECMAscript is not.
Not a 'dialect'. I learned LISP in the 70's and haven't used it since, but when I learned JavaScript recently I found myself thinking it was LISP-like. I think that's due to 2 factors: (1) JSON is a list-like associative structures and (2) it's seems as though JS 'objects' are essentially JSON. So even though you don't write JS programs in JSON as you would write LISP in lists, you kind of almost do.
So my answer is that there are enough similarities that programmers familiar with LISP will be reminded of it when they use JavaScript. Statements like JS = LISP in a Java suit are only expressing that feeling. I believe that's all there is to it.
Yes, it is. Quoting Crockford:
"JavaScript has much in common with Scheme. It is a dynamic language. It has a flexible datatype (arrays) that can easily simulate s-expressions. And most importantly, functions are lambdas.
Because of this deep similarity, all of the functions in [recursive programming primer] 'The Little Schemer' can be written in JavaScript."
http://www.crockford.com/javascript/little.html
On the subject of homoiconicity, I would recommend searching that word along with JavaScript. Saying that it is "not homoiconic" is true but not the end of the story.
I think that ECMAScript is a dialect of LISP in the same sense that English is a dialect of French. There are commonalities, but you'll have trouble with assignments in one armed only with knowledge of the other :)
I find it interesting that only one of the three keynote presentations highlighted for the 4th European Lisp Symposium directly concerns Lisp (the other two being about x86/JVM/Python and Scala).
"dialect" is definitely stretching it too far. Still, as someone who has learned and used Python, Javascript, and Scheme, Javascript clearly has a far Lisp-ier feel to it (and Coffeescript probably even more so) than Python.
As for why the European Lisp Symposium would want to portray Javascript as a Lisp, obviously they want to piggyback on the popularity of the Javascript for which the programmer population is many, many times larger than all the rest of the Lisp dialects in their list combined.
During my routine work, i happened to write the chained javascript function which is something like LINQ expression to query the JSON result.
var Result = from(obj1).as("x").where("x.id=5").groupby("x.status").having(count("x.status") > 5).select("x.status");
It works perfectly and give the expected result.
I was wondering this looks awesome if the code is written like this (in a more readable way)
var Result = from obj1 as x where x.status
groupby x.status having count(x.status) > 5
select x.status;
is there a way to achieve this??
Cheers
Ramesh Vel
No. JavaScript doesn't support this.
But this looks quite good too:
var Result = from(obj1)
.as("x")
.where("x.id=5")
.groupby("x.status")
.having(count("x.status") > 5)
.select("x.status");
Most people insist on trying to metaprogram from inside their favorite language. That doesn't work if the language doesn't support metaprogramming well; other answers have observed that JavaScript does not.
A way around this is to do metaprogramming from outside the language, using
program transformation tools. Such tools can parse source code, and carry out arbitrary transformations on it (that's what metaprogramming does anyway) and then spit the revised program.
If you have a general purpose program transformation system, that can parse arbitrary languages, you can then do metaprogramming on/with whatever language you like. See our DMS Software Reengineering Toolkit for such a tool, that has robust front ends for C, C++, Java, C#, COBOL, PHP, and ECMAScript and a number of other programming langauges, and has been used for metaprogramming on all of these.
In your case, you want to extend the JavaScript grammar with new syntax for SQL queries, and then transform them to plain JavaScript. (This is a lot like Intentional Programming)
DMS will easily let you build a JavaScript dialect with additional rules, and then you can use its program transformation capabilities to produce the equivalent standard Javascript.
Having said, that, I'm not a great fan of "custom syntax for every programmer on the planet" which is where Intentional Programming leads IMHO.
This is a good thing to do if there is a large community of users that would find this valuable. This idea may or may not be one of them; part of the problem is you don't get to find out without doing the experiment, and it might fail to gain enough social traction to matter.
although not quite what you wanted, it is possible to write parsers in javascript, and just parse the query (stored as strings) and then execute it. e.g.,using libraries like http://jscc.jmksf.com/ (no doubt there are others out there) it shouldnt be too hard to implement.
but what you have in the question looks great already, i m not sure why you'd want it to look the way you suggested.
Considering that this question is asked some years ago, I will try to add more to it based on the current technologies.
As of ECMAScript 6, metaprogramming is now supported in a sense via Symbol, Reflect and Proxy objects.
By searching on the web, I found a series of very interesting articles on the subject, written by Keith Kirkel:
Metaprogramming in ES6: Symbols and why they're awesome
In short, Symbols are new primitives that can be added inside an object (without practically being properties) and are very handy for passing metaprogramming properties to it among others. Symbols are all about changing the behavior of existing classes by modifying them (Reflection within implementation).
Metaprogramming in ES6: Part 2 - Reflect
In short, Reflect is effectively a collection of all of those “internal methods” that were available exclusively through the JavaScript engine internals, now exposed in one single, handy object. Its usage is analogous to the Reflection capabilities of Java and C#. They are used to discover very low level information about your code (Reflection through introspection).
Metaprogramming in ES6: Part 3 - Proxies
In short, Proxies are handler objects, responsible for wrapping objects and intercepting their behaviors through traps (Reflection through intercession).
Of course, these objects provide specific metaprogramming capabilities, much more restrictive compared to metaprogramming languages, but still can provide handy ways of basic metaprogramming, mainly through Reflection practices, in fact.
In the end, it is worth mentioning that there is some worth-noticing ongoing research work on staged metaprogramming in JavaScript.
Well, in your code sample:
var Result = from(obj1)
.as("x")
.where("x.id=5")
.groupby("x.status")
.having(count("x.status") > 5)
.select("x.status");
The only problem I see (other than select used as an identifier) is that you embed a predicate as a function argument. You'd have to make it a function instead:
.having(function(x){ return x.status > 5; })
JavaScript has closures and dynamic typing, so you can do some really nifty and elegant things in it. Just letting you know.
In pure JS no you can not. But with right preprocessor it is possible.
You can do something similar with sweet.js macros or (God forgive me) GPP.
Wat you want is to change the javascript parser into an SQL parser. It wasn't created to do that, the javascript syntax doesn't allow you to.
What you have is 90% like SQL (it maps straight onto it), and a 100% valid javascript, which is a great achievement. My answer to the question in the title is: YES, metaprogramming is possible, but NO it won't give you an SQL parser, since it's bound to use javascript grammar.
Maybe you want something like JSONPath if you've got JSON data. I found this at http://www.json.org/. Lots of other tools linked to from there if it's not exactly what you need.
(this is being worked on as well: http://docs.dojocampus.org/dojox/json/query)
Is ruby strongly or weakly typed ?
Presumably the same is true for Javascript.
Ruby is "strong typed".
Strong typing means an object's type (not in the OOP sense, but in a general sense) is checked before an operation requiring a certain type is executed on it.
Weak typed means that no checking is done to ensure that the operation can succeed on the object. (For example, when a function accesses a string like and array of floats, if no type checking is done then the operation is allowed)
Edit:
It's been 6 years since this answer was posted and I think it warrants some extra clarifications:
Over the years the notion that "type safety is a dial not an absolute" started to be used in favor of the binary meaning (yes/no)
Ruby is "stronger" typed (with an "er") than most typical dynamic languages. The fact that ruby requires explicit statements for conversion IE: Array("foo"), "42".to_i, Float(23), brings the Ruby typing dial closer to the "Strong Typed" end of spectrum than the "weak typed".
So I would say "Ruby is a stronger typed dynamic language than most common dynamic languages"
Wikpedia labels it as "dynamic ('duck') typed".
Regarding Pop's comment about it being "strong-typed" - I'm not sure his explanation actually fits with what goes on under the covers. The MRI doesn't really "check" to see if an operation can be performed on an object; it just sends the object the message, and if that object doesn't accept that message (either by a method declaration or by handling it in #method_missing) it barfs. If the runtime actually checked to make sure operations were possible, #method_missing wouldn't work.
Also, it should be noted that since everything in Ruby is an object (and I do mean everything), I'm not sure what he said about "not in an oo-sense" is accurate. In Ruby, you're either an object or a message.
While you can get into arguments about the definition of those term I'd say:
Ruby dynamically and strongly typed while JavaScript is dynamically and weakly typed.
IMHO Ruby is strongly but dynamically typed.
I would consider these languages duck typed.
The over-simplified answer is that both ruby and javascript are weakly typed.
However this question is not quite as clear-cut as it may seem - see this wikipedia article for a more in-depth discussion on the difference between strongly and weakly typed languages.
I just stumbled-on this old thread but thought it proper that I could offer my opinion. (No, I'm not "hijacking" a zombie-thread.)
My colloquial interpretation of the term "strongly typed™" specifically refers to "compile time." (Which is something that many languages today, including Ruby, "simply do not have.")
For instance, a simple assignment statement such as a = b; could be judged by the compiler to be acceptable or not, based on its assessment of the "types" of a and b, and based on provisions for type-conversion (if applicable) provided by the programmers. If the statement was judged unacceptable, a compile-time error would be thrown and no "executable" would ever be produced.
This notion, of course, is not compatible with the fundamental design precepts of languages such as Ruby, PHP, Perl, JavaScript, or a great many other languages that are in extremely-wide (and, extremely-successful) use today. (Mind you, I do not mean this as a "judgment" either for or against them. They are what they are, and they sure do bring home the bacon.)
Because these languages do not have a "compile time," to my(!) colloquialism they cannot be called, "strongly typed." They are obliged to make decisions at runtime which, by their design, could not have been made sooner.
(Also please note that I am specifically excluding from consideration the various "lint tools" that have emerged for this-or-that language in an effort to catch more bugs in advance. These are very useful, yes yes, but not the same thing.)
(I am also purposely excluding various excellent(!) tools that generate source-code in the various target-languages in question ... for the same reasons.)
And – I say once again – I am making a classification, not a judgment.