I have this question.
If I've a dynamic language divided in unities(subprograms). Is it possible that this language has a static scope?
In case that YES, how it's expressed in the symbols table? this has a field in each row that represent the static chain like the A.R. in Algol style language?
Most languages have static scope. That includes many dynamic langauges (Python, Ruby, Javascript and even Perl if you use my to declare your variables).
In case that YES, how it's expresed in the symbols table?
The same way it is in any other language. If you encounter a variable declaration (where in some languages "declaration" means "the first time that the variable is assigned to"), the variable is added to the table. Once you reach the end of the scope, it is removed from the table. In some languages the rules may be a bit more complicated (for example in Javascript the variable will be in scope even before its declaration), but that's basically it.
Related
I've seen some Rust codebases use the #[repr(C)] macro (is that what it's called?), however, I couldn't find much information about it but that it sets the type layout in memory to the same layout as 'C's.
Here's what I would like to know: is this a preprocessor directive restricted to the compiler and not the language itself (even though there aren't any other compiler front-ends for Rust), and why does Rust even have a memory layout different than that of Cs? (it's just that I've never had to do this in another language).
Here's a nice situation to demonstrate what I meant: if someone creates another compiler for Rust, are they required to implement this macro, or is it a compiler specific thing?
#[repr(C)] is not a preprocessor directive, since Rust doesn't use a preprocessor 1. It is an attribute. Rust doesn't have a complete specification, but the repr attribute is mentioned in the Rust reference, so it is absolutely a part of the language. Implementation-wise, attributes are parsed the same way all other Rust code is, and are stored in the same AST. Rust has no "attribute pass": attributes are an actual part of the language. If someone else were to implement a Rust compiler, they would need to implement #[repr(C)].
Furthermore, #[repr(C)] can't be implemented without some compiler magic. In the absence of a #[repr(...)], Rust compilers are free to arrange the fields of a struct/enum however they want to (and they do take advantage of this for optimization purposes!).
Rust does have a good reason for using it's own memory layout. If compilers aren't tied to how a struct is written in the source code, they can do optimisations like not storing struct fields that are never read from, reordering fields for better performance, enum tag pooling2, and using spare bits throughout NonZero*s in the struct to store data (the last one isn't happening yet, but might in the future). But the main reason is that Rust has things that just don't make sense in C. For instance, Rust has zero-sized types (like () and [i8; 0]) which can't exist in C, trait vtables, enums with fields, generic types, all of which cause problems when trying to translate them to C.
1 Okay, you could use the C preprocessor with Rust if you really wanted to. Please don't.
2 For example, enum Food { Apple, Pizza(Topping) } enum Topping { Pineapple, Mushroom, Garlic } can be stored in just 1 byte since there are only 4 possible Food values that can be created.
What is this?
It is not a macro it is an attribute.
The book has a good chapter on what macros are and it mentions that there are "Attribute-like macros":
The term macro refers to a family of features in Rust: declarative macros with macro_rules! and three kinds of procedural macros:
Custom #[derive] macros that specify code added with the derive attribute used on structs and enums
Attribute-like macros that define custom attributes usable on any item
Function-like macros that look like function calls but operate on the tokens specified as their argument
Attribute-like macros are what you could use like attributes. For example:
#[route(GET, "/")]
fn index() {}
It does look like the repr attribute doesn't it 😃
So what is an attribute then?
Luckily Rust has great resources like rust-by-example which includes:
An attribute is metadata applied to some module, crate or item. This metadata can be used to/for:
conditional compilation of code
set crate name, version and type (binary or library)
disable lints (warnings)
enable compiler features (macros, glob imports, etc.)
link to a foreign library
mark functions as unit tests
mark functions that will be part of a benchmark
The rust reference is also something you usually look at when you need to know something more in depth. (chapter for attributes)
To the compiler authors out there:
If you were to write a rust compiler, and wanted to support things like the standard library or other crates then you would 100% need to implement these. Because the libraries use these and need them.
Otherwise I guess you could come up with a subset of rust that your compiler supports. But then most people wouldn't use it..
Why does rust not just use the C layout?
The nomicon explains why rust needs to be able to reorder fields of structs for example. For reasons of saving space and being more efficient. It is related to, among other things, generics and monomorphization. In repr(C) fields of structs must be in the same order as the definition.
The C representation is designed for dual purposes. One purpose is for creating types that are interoperable with the C Language. The second purpose is to create types that you can soundly perform operations on that rely on data layout such as reinterpreting values as a different type.
I'm working with Delphi 10.4.
At some places of my code I have to write long identifiers on long statements (e.g. ProductsForSale.fieldByName('quantity').asInteger * ..... / .... etc.). Is there a way to assign a friendly alias (e.g. TheCost) to this piece of code to substitute it everywhere in the application?
I don't want to use a variable or a function to do this. Only text substitution.
No, Delphi (and Pascal) knows
neither aliases (using a different name for a type/variable/function still needs you to define it anew),
nor macros (executing code in the compiler's context is very limited, mostly definings and conditions).
Even if, chances are you'd have to define it bound to a given context/scope: i.e. your favorite alias TooMuchToType might access three variables named one, two and three, but as per scope those variable's types can vary drastically. Its usage would be prone to obfuscated code and a lot of hassle the compiler has to go thru when trying to give you an error message he wants you to understand.
Why not doing exactly that at the end, but in the opposite way? First using a placeholder and when you're done you replace all of them with the actual code. Otherwise this is bascially what functions are there for, if you want it or not.
What indicator do you use for member declaration in F#? I prefer
member a.MethodName
this is to many letters and x is used otherwise.
I do almost always use x as the name of this instance. There is no logic behind that, aside from the fact that it is shorter than other options.
The options that I've seen are:
member x.Foo // Simply use (short) 'x' everywhere
member ls.Foo // Based on type name as Benjol explains
member this.Foo // Probably comfortable for C# developers
member self.Foo // I'm not quite sure where this comes from!
member __.Foo // Double underscore to resemble 'ignore pattern'
// (patterns are not allowed here, but '__' is identifier)
The option based on the type name makes some sense (and is good when you're nesting object expressions inside a type), but I think it could be quite difficult to find reasonable two/three abbreviation for every type name.
Don't have a system. Wonder if I should have one, and I am sure there will be a paradigm with its own book some day soon. I tend to use first letter(s) of the type name, like Benjol.
This is a degree of freedom in F# we could clearly do without. :)
I tend to use some kind of initials which represent the type so:
type LaserSimulator =
member ls.Fire() =
I largely tend to use self.MethodName, for the single reason that self represents the current instance by convention in the other language I use most: Python. Come to think of it, I used Delphi for some time and they have self as well instead of this.
I have been trying to convert to a x.MethodName style, similar to the two books I am learning from: Real World Functional Programming and Expert F#. So far I am not succeeding, mainly because referring to x rather than self (or this) in the body of the method still confuses me.
I guess what I am saying is that there should be a meaningful convention. Using this or self has already been standardised by other languages. And I personally don't find the three letter economy to be that useful.
Since I work in the .NET world, I tend to use "this" on the assumption that most of the .NET people who encounter F# will understand its meaning. Of course, the other edge of that sword is that they might get the idea that "this" is the required form.
.NET self-documentation concerns aside, I think I would prefer either: "x" in general, or -- like Benjol -- some abbreviation of the class name (e.g. "st" for SuffixTrie, etc.).
The logic I use is this: if I'm not using the instance reference inside the member definition, I use a double underscore ('__'), a la let-binding expressions. If I am referencing the instance inside the definition (which I don't do often), I tend to use 'x'.
I learned to program with delphi, and i always liked the object pascal code style, looks very intuitive and clean.
When you look at the variable declaration, you know what are you dealing with..
A fast summary:
Exception E EMyError
Classes and Types T TMyClass
Fields in classes f fVisible
Events On OnMouseDown
Pointer types P PMyRecord
Property Get Something Set SetSomething
It's too bad to use this identifier naming style in C++ C# Java, or any other language code?
Aside from taste and cultural issues (as already pointed by Mason)
There might be reasons why a convention is tied to a certain language, and the other languages might also have reasons for theirs.
I can only quickly think of a few examples though:
On languages that don't require a pointer type to be defined before use (like most non-Borland Pascals, C etc), the "P" one is usually rarely necessary.
Other languages might also have additional means of disambiguating (like in C where often types are upper cased, and the variables or fields get the lowercase identifier), and does not need "T". (strictly speaking Delphi doesn't neither at least for fields, since identifiers are somewhat context dependantly looked up (likeseparate namespaces for fields and types), but the convention is older than that feature)
BTW, you forget "I" for interface, and enum names being prefixed with some prefix derived from the base type name (e.g.
TStringsDefined = set of (sdDelimiter, sdQuoteChar, sdNameValueSeparator,
sdLineBreak, sdStrictDelimiter)
)
etc.
Hmm, this is another language specific bit, since Object Pascal always adds enum names to the global space (instead of requiring enumtype.enumname). With a prefix there is less polution of the global space.
That is one of my pet peeves with Delphi btw, the lack of import control (Modula2 style IMPORT QUALIFIED , FROM xxx IMPORT. Extended Pascal also has some of this)
As far as I know, the T, E, F, and P prefixes are only commonly used in Delphi programming. They're a standard part of the idiom here, but in C# or Java they'd look out of place.
Get and Set are pretty standard across object-oriented programming. Not sure about the On prefix, but it wouldn't surprise me to find that that's common in any event-driven framework.
I come across the following in code.
_name1
_name2
smeEGiGross:
In general, what does _name1 underscore mean in Delphi 4?
I think it's just a common practice to begin variable names with underscores.
Rules for variable (and component) names in Delphi:
Name can be any length but Delphi uses only first 255 characters.
First character must be letter or underscore not a number.
You cannot use any special characters such as a question mark (?), but you can
use an underscore (_).
No spaces area allowed in the name of a variable.
Reserved words (such as begin, end, if, program) cannot be used as variables.
Delphi is case insensitive – it does not matter whether capital letters are
used or not. Just make sure the way variables or components are used is
consistent throughout the program.
It's a convention to help determine scope of a variable by its name, like private class members. The original author probably uses C++ as well.
In Delphi, I prefer to prefix fields with "F", method parameters with "a" (argument) and local variables with "l".
Update:
Another place you might see underscores is after certain identifiers in code generated with WSDLImp or TLBImp to avoid confusion with existing Delphi identifiers. For example, unless you specify otherwise, "Name" is renamed (no pun intended) to "Name_".
To add to the answer of phoenix:
* You can use reserved words as identifiers, but you must add a & sign: &then,
&unit.
I only use this if another name Ãs not apropriate.
I associate leading underscores with C/C++ not with Delphi. The C syntax is more character oriented (like {, }, || and &&) so the underscores fit perfectly. While the Delphi/Pascal syntax is more text oriented (begin, end, or, and) so the underscores look a bit strange as you don't expect them there.
It's regularly used for scope.
I declare all my private variables with a _ at the beginning, which is more common in C#/C++.
It's for readability and doesn't necessarily mean anything.
I cannot say what the author of the code you have in mind was thinking, but an underscore prefix has a fairly well recognised convention in relation to COM.
Members in a COM interface that have an underscore prefix are (or were) hidden by default by interface browsers/inspectors, such as VB's library browser etc. This is used when members are published by necessity but are not intended to be used directly.
The _AddRef and _Release members of the IUnknown interface are perhaps the most obvious example of this.
I've adopted this convention myself, so that for example if I declare a unit implementation variable that is exposed through the unit interface via an accessor function I will name the variable with an underscore prefix. It's not strictly necessary in that sort of example but it acts as documentation for myself (and anyone else reading my code that is aware of the convention, which is fairly self-evident from the context).
Another example is when I have a function pointer that may refer to different functions according to runtime conditions so the actual functions that the pointer may refer to are not intended to be called directly but are instead intended to be invoked via the function pointer.
So speaking for myself, I use it as a warning/reminder.... Proceed with caution you are not expected to reference this symbol directly.