A language that is actually low level enough (i.e. to create an operating system, or embed assembly in its syntax, or..) but also high level enough.
"Enough" is a relative term.. but low level languages have some qualities and high level languages have some known qualities.
High and low are also relative.. but for example as a point of reference, everyone knows Assembly is low level. And if one can embed assembly into a language, that almost makes it low level enough to do anything... Some HighLevelLowLevelLanguage's have the ability to embed assembly, but it is not mandatory for a HighLevelLowLevelLanguage to embed assembly.
An example of a HighLevelLowLevelLanguage that doesn't necessarily embed assembly is one like OberonLanguage (which compiles itself and compiles an OS, but has high level features such as garbage collection, automatic strings, arrays, etc).
Another example is FreePascal, which one can write an operating system in, but it also has extremely high level features available such as Ansistrings, Widestrings, dynamic arrays, optional object orientation.
- [When did Ansistrings become 'high level'? I guess 'high level' must be extremely relative.]
- C is low level, assembler is low level. Love to use C's ansistrings and assembler's ansistrings, don't we now? Relatively, ansistrings, widestrings, dynamic arrays, and object orientation are higher level than assembly and C code. Since assembly and C are very popular low level implementations of languages, we can use them as one relativity point. You seem to have an obsession over arguing about ansistrings, even though that was not just the only type mentioned.
- [I just happen to find your concept of 'high level features' to be ridiculously 'low level'.]
- Reference counting is somewhat of a form of GarbageCollection, and reference counted arrays and strings and such things are just one small feature that makes a language more higher level than other lower level languages. If you feel that garbage collection or reference counting can be implemented into lower level languages, then that's fine.. that is exactly what a HighLevelLowLevelLanguage is!
- DiscoveryOfDefinitionThroughArgument?
Another example is Ada, which can go to the bare metal.. but also has high level features.
A HighLevelLowLevelLanguage should be able to compile itself without help from other low level languages, since it is low level enough to do so. This is not a mandatory qualification for whether it is a HighLevelLowLevelLanguage though.
Actually, it seems a lot of the Algol style languages are HighLevelLowLevel?.
C++ can be considered a HighLevelLowLevelLanguage.
Current mainstream implementations of Java, PHP, Ruby are not so low level, and doesn't qualify as a HighLevelLowLevelLanguage.
Arguments could be made based on some special version of Java such as a Java compiler written for lower level purposes... but for simplicity sake this article discusses the popular implementations.. i.e. the Java Run Time, the PHP scripting language, the Ruby scripting language, etc.
Being able to compile is not enough to qualify as a HighLevelLowLevelLanguage otherwise any language that can a) write bytes into a file and b) call system() or the like to execute external programs qualifies. The embedding of assembly was on the right track. I think better criteria are a) being able to execute client processes in the scope of the application and b) being able to store these externally. In the simplest case these may be assembled byte blobs that are run in a sub process (but can take direct parameters from the parent).
That is why it is made clear in this article that that is not mandatory for qualification, it is just usually one of the qualities. Example C can compile itself.
[I'd say that the basic criterion for a low-level language is the ability to write device-drivers for new pieces of hardware - more explicitly, to support this through appropriate syntax and semantics (so you don't need to write another language inside your own to compile to BLOBs upon which you 'call system() or the like'. This does require the ability to control representation and memory placement down to the bit level, but does not require direct access to assembler or pointers (the applications of which may be abstracted declaratively).]
[There is, of course, no such thing as a 'highest' level language, but I'd argue that an 'appropriately high-level' language is one that lets you express your intent and skip expressing the arbitrary details about which you are unconcerned - any time you are forced to express a detail that you consider arbitrary (e.g. the size of an array, the sort algorithm - even the choice of sort algorithm, the storage mechanism for strings, etc.), it is an indicator that the language you are working in is lower level than you'd desire for the problem. Of course, no fixed well-defined language can be 'appropriately high level' for all problems. One could attempt to stratify different base languages (on the 'high-level-ness' of their primtives), but I think it is better argued that it is the ability to readily extend the language to BOTH support your expression of intent AND allow you to leave out the details about which you are unconcerned that most clearly marks a 'high level' language. This is affected by syntax; if you are stuck writing explicit 'for' loops when you want a 'foreach' (and you, for example, don't care about the order or how it gets from one to the other), then the language is failing to be properly extensible. Under this definition, one can note that most languages have limits on how far they can rise before they start losing efficiency (crossing 'layers' of abstraction), run afoul of GreenspunsTenthRuleOfProgramming (see KeyLanguageFeatures), or slam into walls (syntactic limits; limited ability to store contextual information about programmer intent, etc.), and sometimes one causing the other (e.g. when programmer intent is for efficiency or realtime guarantees, but crossing layers of abstraction is hurting efficiency or violating guarantees). These limits, thus, determine how 'high level' a language has the potential to be. Of course, the implemented extensions and libraries determine the more present-tense form.]
- Specifying a file extension that must only be 3 characters in length can be useful, if the operating system didn't allow extensions that were longer than 3 characters. If it did allow longer than 3 characters, then setting a limit of 20 or 50 may be beneficial so that the software is not exploited. A high level language should have features to protect exploits.
- [How does this non-sequitur comment fit into the above context?]
- High level languages, especially web languages, should provide features to improve productivity. Reimplementing security checks yourself reduces productivity. Therefore a high level language does not mean that one should not be able to specify his string type or array length like you say.
- [Of course a high-level language doesn't mean that one shouldn't be able to specify string type or array length. It means that one should not have to specify his string type or array lengths if one doesn't care. If one cares, that's a different story. If one cares, it is not "arbitrary".]
- Then we agree, as this is the approach Qomp takes. One can specify his string length, or just use a lazy automatic ansistring or unicode string. One can define an array that is fixed if he wants, but he can also define a dynamic array that can grow on demand.
- [This page isn't a forum for discussion as to whether QompItself is a HighLevelLowLevelLanguage (or HighLevelLowLevelInfrastructure).]
- In addition, specifying a known fixed array of three items, or a known fixed enumeration can be extremely useful. If there are only three command line options to choose from, then they can be looped through a fixed array without security risks if there is range checking. Languages should prevent exploits to save programmers time, and higher level languages can contain features to save a programmer time from implementing an reinventing his own range checks and boundaries
- [I am also fond of Safety and TypeSafety, but I consider the question of whether a language is "safe" and whether a language is "high level" to be quite orthogonal.]
- They can be related, but sure they aren't directly one for one. I deal with web security, and a lot of unsafe web programs out there can be hacked due to improper type checking or run time checks of URL variables. For example an integer in a url variable can be injected with SQL injection or html injection, if the incoming type is not converted to an integer first... and is just "a loose weak dynamic string"
- [I suppose the ability to declare, at a high-level, that you want security - and to have the compiler automatically build in TypeSafety, check the inputs to see whether they are well-typed and come from an authorized source and carry the appropriate capabilities, etc. would be a rather nice, high-level language feature. So, yes, they can be related, but in a rather orthogonal fashion: a generically higher-level safe language ought be able to declare safety properties in a (predictably) higher-level manner.]
- In addition, specifying a known fixed array of three items, or a known fixed enumeration can be extremely useful. If there are only three command line options to choose from, then they can be looped through a fixed array without security risks if there is range checking. Languages should prevent exploits to save programmers time, and higher level languages can contain features to save a programmer time from implementing and reinventing his own range checks and boundaries. It adds needless verbosity to a language if you have to implement your own range checks everywhere.. and induces security risks. Especially in an InternetFuture with the internet being dominant, do we worry about security and how high level languages offer more protection.
- [And you are contradicting me... how?]
- Let's agree to argue, or argue to agree. You said "A high-level language is one that lets you express your intent and skip expressing the arbitrary details about which you are unconcerned". But you didn't mention "A high level language shouldn't lead one to believe that one should be unconcerned." IMO Php, Ruby, Perl, and many high level languages do lead one to believe that they should be unconcerned. I have talked to many of the programmers who use those languages, even experts, and they all think that not declaring types and not specifying lengths of anything, is essential in a high level language.
- [The ability to be unconcerned about the details is essential to a high-level language. The ability to get away with not declaring types, not specifying lengths of anything, is essential in a high-level language (though TypeInference can help out a lot, if you still wish to have TypeSafety). The ability to be concerned about the details is essential to a low-level language - one where you need precise access and bit-manipulation to, say, drive your devices. The whole premise of this page - HighLevelLowLevelLanguage - is that a single language can cross the entire continuum, and I don't disagree.]
- Since higher level languages tend to be more productive, and since I consider "types" and boundaries to be one productive feature (as opposed to lower level assembly where you cannot even define boundaries).... one can still argue that a language with only fixed arrays is high level.. but nowadays people tend to think higher level languages are ones without any boundaries or types.. Since in some cases higher level means "more productive" and in many cases boundaries and types can make a programmer more productive, I think this high level low level thing is murky.. for sure.
- [Higher level languages should generally be more productive because you don't waste your time dealing with details about which you (frankly) don't give a damn. But that doesn't mean that all productive features are a consequence of being higher level. For example, having a good compiler with detailed warnings and errors, a good IDE and debugger, good source-control, etc. can all make a programmer more productive and aren't part of the language or its 'level' of abstraction. Dealing with reduced errors because a language provides safety also makes one more productive (fewer 'obvious' errors shipped, reduced quantity of unit-tests needed, etc.). Don't confuse productivity with "high level". That way lies much murkiness.]
- [As far as the 'can be unconcerned' -> 'should be unconcerned' - that's largely a cultural/community issue, not part of the language itself. Most of those languages have a mechanism for ramping up security checks and safety a bit (e.g. disabling certain calls), and that's probably enough for most of the purposes to which they apply them.]
- [Fundamentally, OperatingSystems (including their applications) need a better SecurityModel (such as the CapabilitySecurityModel) before we can get real security. The existing infrastructure is failing us, here. And more common two-part specification policies wouldn't hurt, either (I'll tell you what I'm gonna tell you, then I'll tell you what I'm tellin' you) where security needs to be at its highest - e.g. "SQL updates X once; insert into X(f,g,h) values (a,b,c),(d,e,f)" - these policies basically provide per-call extra safety checks to resist code-injection of any sort.]
Examples:
See Also: HighLevelLanguage, LowLevelLanguage