Is the word if in an if statement called a keyword? I'm aware that the PHP documentation calls it a language construct. The C# documentation doesn't list it as a keyword. I don't know what to call it.
Related
This question already has an answer here:
What is an equivalent replacement for std::unary_function in C++17?
(1 answer)
Closed 1 year ago.
I have been reading Effective STL by Meyers.
I came across some sections which mention function adapter objects, such as not1, bind1st, bind2nd. There are apparently a range of such function adapter objects, however I have never encountered these before. Another example is mem_fun and mem_fun_ref.
Many of these inherit from unary_function and binary_function. Some links are provided below.
https://en.cppreference.com/w/cpp/utility/functional/unary_function
https://en.cppreference.com/w/cpp/utility/functional/binary_function
https://en.cppreference.com/w/cpp/utility/functional/mem_fun
These objects are depreciated in C++ 11, which probably explains why I had not encountered them before.
Why are they deprecated, and what replaces them? My instinct tells me that a lambda can replace such function objects, and while reading the book it did occur to me that some of the sorting operations on STL containers can be described using a lambda instead of a function object.
Does a lambda completely replace these "adapter functions".
If so, are function objects still useful post C++ 11? If they have been made obsolete in the STL, does this mean function objects are obsolete everywhere in C++ 11 or do they still have uses?
As a final comment, are there any modern books on STL which serve as a good replacement for Meyers Effective STL? I have learned a lot from reading his book but there are probably more sections than I currently realize which contain obsolete information.
You can use one of these:
Lambda expression
std::bind
std::mem_fn
Does a lambda completely replace these "adapter functions".
Since C++14, lambdas can do everything that the deprecated and later removed functor templates can do.
If so, are function objects still useful post C++ 11?
Lambdas are function objects.
If you mean to ask whether it's still useful to write named function class templates: Yes, it's still occasionally useful.
Lambdas can be just as reusable by writing a named function that returns the lambda.
Can you add ... an example?
Here's an example:
constexpr auto
reusable_lambda() noexcept
{
return []{
return "Just an example";
};
}
In Clojure context, some define the term form as “any valid code,” and some as “any valid code that returns a value.” So both the numeral 1729 and the string Hello! is a form. Likewise (fn is not a form. Is an undefined symbol, say my-val, a form?
What is the difference between an expression and a form?
What is the difference between an expression and a function?
There are some good answers to this question at Are Lisp forms and Lisp expressions same thing?
The key thing to think about is that there are different points in the lifecycle. We start with text "(+ 1 2)" which is then read into Clojure data (a list containing a symbol and two numbers). Often in Lisps "expression" is used to mean the former and "form" is used to mean the latter. In practice, I do not find that people are at all consistent with this usage and often use both terms for both things.
If you take "form" to mean "something which can be evaluated", then 1729 or "Hello!" or the symbol my-val are all forms. When my-val is evaluated it is resolved in the current namespace, perhaps to a function instance, which is invokable. Functions are really important only at evaluation time, when they can be invoked.
Another interesting aspect are macros, which allow you to create new syntax. Note that macro expansion happens after reading though, which means that while you can create new syntax, it still must follow some basic expectations that are encoded into the reader (namely that invocations follow the pattern (<invokable> <args...>)). Note that macros work on read but unevaluated forms (data, not text) and must produce new forms.
What is the difference between an expression and a form?
In my opinion form in a context of Clojure is something a compiler deals with. Some forms are valid expressions while others are "special" forms (i.e. macros).
What is the difference between an expression and a function?
Any function is an expression.
Is an undefined symbol, say my-val, a form?
I would say it is a valid expression (hence form) which yields to a compile time exception.
Likewise (fn) is not a form
It seems like you are referring to some source, where this was declared, could you provide a link?
We have a course whose project is to implement a micro-scheme interpreter in C++. In my implementation, I treat 'if', 'define', 'lambda' as procedures, so it is valid in my implementation to eval 'if', 'define' or 'lambda', and it is also fine to write expressions like '(apply define (quote (a 1)))', which will bind 'a' to 1.
But I find in racket and in mit-scheme, 'if', 'define', 'lambda' are not evaluable. For example,
It seems that they are not procedures, but I cannot figure out what they are and how they are implemented.
Can someone explain these to me?
In the terminology of Lisp, expressions to be evaluated are forms. Compound forms (those which use list syntax) are divided into special forms (headed by special operators like let), macro forms, and function call forms.
The Scheme report desn't use this terminology. It calls functions "procedures". Scheme's special forms are called "syntax". Macros are "derived expression types", individually introduced as "library syntax". (The motivation for this may be some conscious decision to blend into the CS academic mainstream by scrubbing some unfamiliar Lisp terminology. Algol has procedures and a BNF-defined syntax, Scheme has procedures and a BNF-defined syntax. That ticks off some sort of familiarity checkbox.)
Special forms (or "syntax") are recognized by interpreters and compilers as a set of special cases. The interpreter or compiler may handle these forms via function-like bindings in some internal table keyed on symbols, but it's not the program-visible binding namespace.
Setting up these associations in the regular namespace isn't necessarily wrong, but it could be problematic. If you want both a compiler and interpreter, but let has only one top-level binding, that will be an issue: who gets to install their procedure into that binding: the interpreter or compiler? (One way to resolve that is simple: make the binding values cons pairs: the car can be the interpreter function, the cdr the compiler function. But then these bindings are not procedures any more that you can apply.)
Exposing these bindings to the application is problematic anyway, because the semantics is so different between interpretation and compilation. If your interpretation is interpreted, then calling the define binding as a function is possible; it has the effect of performing the definition. But in a compiled interpretation, code depending on this won't work; define will be a function that doesn't actually define anything, but rather compiles: it calculates and returns a compiled fragment written in some intermediate representation.
About your implementation, the fact that (apply define (quote (a 1))) works in your implementation raises a bit of a red flag. Either you've made the environment parameter of the function optional, or it doesn't take one. Functions implementing special operators (or "syntax") need an environment parameter, not just the piece of syntax. (At least if we are developing a lexically scoped Scheme or Lisp!)
The fact that (apply define (quote (a 1))) works also suggests that your define function is taking quote and (a 1) as arguments. While that is workable, the usual approach for these kinds of syntax procedures is to take the whole form as one argument (and a lexical environment as another argument). If such a function can be called, the invocation looks something like like (apply define (list '(define a 1) (null-environment 5))). The procedure itself will do any necessary destructuring on the syntax, and checking for validity: are there too many or too few parameters and so on.
This question already has answers here:
What is the difference between a "function" and a "procedure"?
(18 answers)
Closed 8 years ago.
I read many many articles about difference between function and procedure but there is something I'm in doubt about.
Do we call following statement a function or a procedure in terminology?
void f() { return; }
Some articles says function returns value but procedure does not.
Some other article says if a function returns one value called function but if it returns more than one value it called procedure.
In the standard terminology of C and C++, no. It's a function whether or not it returns anything, or even if it doesn't return.
In more general computing vocabulary, and the terminology of other programming languages, it might be called a "procedure" or a "subroutine" (and perhaps a few other terms) if it doesn't return a value.
A procedure is a function that do not return a result!
There is no such term as procedure in C and C++ languages. So relative to C and C++ languages your question has no sense. In any other languages the definition of the term procedure can vary.
In C and C++ statement
void f() { return; }
is a function definition.
As Mike annd Grzegorz says, from C Standard point of view there is no difference, but the function term is used by convention.
In other programming language (e.g. basic) that distinction is commonly used depending if return or not a value that function.
As final note: in the C Programming Language book (official C programming language book) from Dennis Ritchie (C creator) the term function is used independently if returns or not a value and that's one of the reason that the term is used indistinctly.
There are various terminologies that means the same in various different languages. Like function used in structured language like c, Method's used in java, procedure, function both used in Scala.
In reality, Procedure is a function really but that doesn't return anything and in C we still refer to it as function.
From the C Standard point of view there is no distinction between functions and procedures (like in e.g. Pascal) or subroutines (like in e.g. Fortran). Both types (i.e. returning void and non-void) are simply named as functions. I believe that C++ just follows this way.
On Page 175 Paragraph 1 of Effective C++ Meyers has this to say about generalized functors and binding:
I find what tr1::function lets you do
so amazing, it makes me tingle all
over. If you're not tingling , it may
be because you're staring at the
definition of ... and wondering what's
going on with the ....
And I agree with him on bind and function. About lambda, Well I understand what lambda does and how it does it, but could someone post a book style mind-blowing snippet or a verbal outline of why lambda is supposed to (in Meyers' terminology) blow my socks off ? I ask because each area of C++ where the placeholder syntax is used seems like a hack to me (yes, I know enough about the functional method, so please no basics), I agree with the way it's used in bind and MPL; However, in the case of lambda I just want it justified so I can decide weather I should enter it into my repertoire.
-- edit --
This SO answer mentions the inlined creation of a functor using just placedholder syntax, he mentions advanced usage, and this is probably what I am after... in advanced usage is it still just inlined creation of functors ?
Based on the comments left above, and the link in the question, the following is the answer I accept (community wiki) :
Boost.Lambda fills the purpose of inline functor creation (that's the term I like). This functionality can be filled by Function + Bind, but it is more verbose than it needs to be, and for simple functors this is unnecessary — e.g., the sort shown in the comments above.
There is obviously semantic overlap between the Function-Bind pair and Lambda — this is a historical artifact, and because Lambda has its raison d'être, it exists in Boost.
What is "cool" about it is that, as with boost foreach and boost parameter, injects/extends syntax into C++ which is not in the language, ie it emulates anonymous functions directly as parameters.