Say we have this block:
int (^aBlock)(BOOL) = ^(BOOL param) { ...
My current understanding of this is: the first int is the return type, (^aBlock)(BOOL) gives the name of the method and the type of its parameter, and = ^(BOOL param) is the parameter's name inside the block ... plus the parameter's type again?
Why is the syntax such that we have to list the parameter type twice? Could the two types ever be different?
It is not quite "listing the parameter type twice", you are in the first case declaring the type of a block variable, and in the second case you are defining a block literal.
Then you are assigning the literal to the value of the variable. You could even do something like this, which is equivalent and better illustrates the fact that these are really two totally independent declarations, despite being associated with an assign statement:
id thisBlock = ^id (id x, NSUInteger idx) {
NSLog(#"x = %#",x);
return x;
};
id (^thatBlock)(id obj, NSUInteger index) = thisBlock;
The fact that they are independent of each other means it's probably not even correct to attempt to provide some kind of transference or inheritance of typing information from the left hand side of the expression to the right. And yes, the types can be different - consider this code compiles and executes just fine:
id (^thatBlock)(NSArray *, NSDictionary *, NSString *) = ^id (id x, id y, id z) {
NSLog(#"x = %#",x);
return x;
};
thatBlock(#[],#{},#"");
Hope this helps!
Why is the syntax such that we have to list the parameter type twice?
The block is designed in this way, and so you can do it like this:
int (^aBlock)(BOOL);
aBlock = ^(BOOL param) {
...
};
It just likes
- (int)aMethodWithParam:(BOOL)param;
- (int)aMethodWithParam:(BOOL)param {
...
}
Could the two types ever be different?
Nope, and what's more, the order of the types should be the same, i.e.:
int (^aBlock)(BOOL, NSString*) = ^(BOOL param, NSString *aString) {
...
};
And here's a clear figure for block:
The code snippet you have given isn't a block declaration: it's a block declaration and a block definition. First, you declare an identifier named aBlock:
int (^aBlock)(BOOL)
then you define a block:
^(BOOL param) { ...
Both of these are parsed and evaluated separately. Since you are assigning one to the other, the compiler does a type-check to make sure that the expression on the left hand side (your aBlock declaration) is of the same type as the expression on the right hand side (the block definition).
So, the answer is, these parts need to be evaluated separately. Since the block definition is being compiled on its own, you have to include the type of param, because otherwise the compiler won't know what type it should be. (Yes, you could make an exception in this case, and look across the assignment, but everywhere else in the C language you declare an identifier by giving a type first, so why do it differently here?)
But -- you may say -- if that's true why didn't I have to define the return type (int) on the right-hand side?
Very astute of you. The answer is that, when writing a block expression, you don't need to define the return type, because the compiler can infer it from the return statement (or lack thereof) inside the block.
(So why do you have to include return types with function definitions? Well, history, I guess. Programming language definitions were created by imperfect humans.)
According to Ry's Objective C Tutorial:
Blocks use all the same mechanics as normal functions. You can declare a block variable just like you would declare a function.
NSInteger (^BlocksAddition)(NSInteger x,NSInteger y)=^NSInteger(NSInteger x, NSInteger y){
return x+y;
};
NSUInteger result=BlocksAddition(4,5);
NSLog(#"Addition Result:%d",result);
Related
Official docs says that class can be built dynamically like so:
constant A := Metamodel::ClassHOW.new_type( name => 'A' );
A.^add_method('x', my method x(A:D:) { say 42 });
A.^compose;
A.new.x(); # x will be only called on instances
But what if I am building a class and don't assign it to a constant but rather store it in a var (for instance when I need to create a bunch of classes in loop) like so:
my $x = Metamodel::ClassHOW.new_type( name => 'some custom string' );
$x.^add_method('x', my method ($y:) { say $y });
$x.^compose;
But in this case I can call method x both on class ($x.x) and on instance ($x.new.x) though I want it to only be called on instances.
I tried to define method like so:
$x.^add_method('x', my method ($y:D:) { say $y });
but that produces an error:
Invalid typename 'D' in parameter declaration.
Of course I can check defindness of the value inside the method but I want some compile-time guarantees (I want to believe that type checking is done in compile time).
I tried to play with signatures and parameters but couldn't find a way to create an invocant parameter but what is more important I am not sure how to assign signature which I have in a variable to some method.
Change:
my $x = ...
to:
my constant x = my $ = ...
In full:
my constant x = my $ = Metamodel::ClassHOW.new_type( name => 'some custom string' );
x.^add_method('x', my method (x:D $y:) { say $y });
x.^compose;
x = Metamodel::ClassHOW.new_type( name => 'another custom string' );
...
I want some compile-time guarantees (I want to believe that type checking is done in compile time).
By making the constant's RHS be a variable declaration, you blend static compile-time aspects with dynamic run-time ones.
(BTW, the my before constant is just me being pedantic. A plain constant like you've used is equivalent to our constant which is less strict than my constant.)
I note the error message for a non-instance is different:
Type check failed in binding to parameter '$y';
expected type some custom string cannot be itself
At a guess that's because the usual message comes from Mu or Any and your class isn't inheriting from either of them.
I am not sure how to assign signature which I have in a variable to some method.
I'll leave that part unanswered.
The best way I can think of to produce a method with types substituted into a signature with Raku today is to use a parametric role to help out, like this:
my role Helper[::T] {
method foo(T $inv:) {}
}
my &meth = Helper.^parameterize(Int).^pun.^lookup("foo");
say &meth.signature;
Which outputs (Int $inv: *%_). Substitute Int with the type you are building.
I am attempting a method swizzle in Obj-C but I would like to pass it a pure C function. This means I need to somehow assign a selector and/or manually build an objc_method struct. Maybe somehow leverage NSInvocation?
My understanding is that due to the fact that Obj-C is a strict superset of C and therefor fully compatible.
What I have going now:
main.m :
#include....
CFStringRef strRet(void) {
return CFSTR("retString");
}
int main(int argc, const char * argv[]) {
#autoreleasepool {
SEL _strRet = sel_registerName("strRet");
//I also tried: SEL _strRet = NSSelectorFromString(#"strRet");
Class bundle = objc_getClass("NSBundle");
method_exchangeImplementations(
class_getInstanceMethod(bundle, sel_registerName("anySelector")),
class_getInstanceMethod(bundle, sel_registerName("_strRet")
);
I have tried putting the C function inside #implementation (which I would like to avoid) and even then it did not work.
You can't swizzle a C function per se; swizzling is based on method lookup which goes through method descriptions (which are represented by the Method type by the runtime functions) and C functions do not have a method description.
However the implementation of a method is just a C function. Such a C function must take a minimum of two arguments, being the object the method is invoked on (the Objective-C implicit parameter self) and the selector (the Objective-C implicit parameter _cmd). When you swizzle a method the replacement implementation, a C function, must have exactly the same type as the original – complete with the two implicit arguments – so your strRet() would not be suitable as is, you would need to change it to:
CFStringRef strRet(NSObject *self, CMD sel, void)
{
return CFSTR("retString");
}
So you have three main choices:
The easiest way is to define a method whose body is your "pure" C function, then swizzle the recommended way (taking care to handle inheritance correctly, see this answer).
If you really want to write a C function and that C function does not need to call the original implementation of the method then:
(a) You need to convert your C function into one which can be used as a method implementation. You can:
If you are writing/have the source of the C function you simply define it to take the two implicit arguments as above. Take the address of this function and cast it to IMP, which is just a typedef for a C function pointer of the appropriate type, for use below.
If you are using a C function whose definition you cannot change then you can do one of:
Write a C wrapper function which takes the extra arguments, ignores them and calls your target C function. Take the address of this wrapper function and cast it to IMP for use below.
Wrap the call to your C function in a block and use imp_implementationWithBlock() to produce an IMP value from it. You can read this article for a description of using imp_implementationWithBlock().
(b) use method_setImplementation() to set the implementation to the IMP value you produced in (a).
If you really want to write a C function and that C function does need to call the original implementation of the method then you will need to add a method to your class whose implementation is your C function – modified/wrapped as in (2), then swizzle your added method with your original method as under (1) so that the original implementation is still available as a method. To add a method you use class_addMethod()
HTH
The key here is finding a mechanism that maps between the function pointer and your context. The simplest way to do that is by generating a new function pointer. You can use imp_implementationWithBlock(), MABlockClosure, or roll your own.
The simplest mechanism to create a new function pointer I've found is to remap the entire function to a new address space. The new resulting address can be used as a key to the required data.
#import <mach/mach_init.h>
#import <mach/vm_map.h>
void *remap_address(void* address, int page_count)
{
vm_address_t source_address = (vm_address_t) address;
vm_address_t source_page = source_address & ~PAGE_MASK;
vm_address_t destination_page = 0;
vm_prot_t cur_prot;
vm_prot_t max_prot;
kern_return_t status = vm_remap(mach_task_self(),
&destination_page,
PAGE_SIZE*(page_count ? page_count : 4),
0,
VM_FLAGS_ANYWHERE,
mach_task_self(),
source_page,
FALSE,
&cur_prot,
&max_prot,
VM_INHERIT_NONE);
if (status != KERN_SUCCESS)
{
return NULL;
}
vm_address_t destination_address = destination_page | (source_address & PAGE_MASK);
return (void*) destination_address;
}
Note that page_count should be large enough to contain all of your original function. Also, remember to handle pages that aren't required anymore and note that it takes a lot more memory per invocation than MABlockClosure.
(Tested on iOS)
I have a method, like so:
- (void) simpleMethod {
var = someValue;
}
I wanted to define a function which exists only within that method (I can do this in python for example). I tried to define it like a normal C function, like this...
- (void) simpleMethod {
var = someValue;
int times1k(int theVar) {
return theVar * 1000;
}
ivar = times1k(var);
}
But Xcode throws various errors. Is it possible to define a function within a method in Objective-C? And if so, how?
No, Objective-C follows the strict C rules on this sort of thing, so nested functions are not normally allowed. GCC allowed them via a language extension but this extension has not been carried over to Clang and the modern toolchain.
What you can do instead is use blocks, which are Objective-C's version of what Python (and most of the rest of the world) calls closures. The syntax is a little funky because of the desire to remain a superset of C, but your example would be:
- (void) simpleMethod {
var = someValue;
// if you have a bunch of these, you might like to typedef
// the block type
int (^times1k)(int) = ^(int theVar){
return theVar * 1000;
};
// blocks can be called just like functions
ivar = times1k(var);
}
Because that's a closure rather than a simple nested function there are some rules you'd need to follow for declaring variables if you wanted them not to be captured at their values when the declaration is passed over, but none that are relevant to your example because your block is purely functional. Also times1k is a variable that you can in theory pass about, subject to following some unusual rules about memory management (or letting the ARC compiler worry about them for you).
For a first introduction to blocks, I like Joachim Bengtsson's article.
Not sure what I'm doing wrong here. I have a struct that is used heavily through my program.
typedef struct _MyStruct {
// ... handful of non-trivial fields ...
} MyStruct;
I expect (read, intend) for lots of parts of the program to return one of these structs, but many of them should be able to return a "null" struct, which is a singleton/global. The exact use case is for the implementing function to say "I can't find what you asked me to return".
I assumed this would be a simple case of defining a variable in a header file, and initializing it in the .c file.
// MyStruct.h
// ... Snip ...
MyStruct NotFoundStruct;
-
// MyStruct.c
NotFoundStruct.x = 0;
NotFoundStruct.y = 0;
// etc etc
But the compiler complains that the initialization is not constant.
Since I don't care about what this global actually references in memory, I only care that everything uses the same global, I tried just removing the initialization and simply leaving the definition in the header.
But when I do this:
MyStruct thing = give_me_a_struct(some_input);
if (thing == NotFoundStruct) {
// ... do something special
}
Th compiler complains that the operands to the binary operator "==" (or "!=") are invalid.
How does one define such as globally re-usable (always the same memory address) struct?
This doesn't directly answer your question, but it won't fit in a comment...
If you have a function that may need to return something or return nothing, there are several options that are better than returning a "null struct" or "sentinel struct," especially since structs are not equality comparable in C.
One option is to return a pointer, so that you can actually return NULL to indicate that you are really returning nothing; this has the disadvantage of having significant memory management implications, namely who owns the pointer? and do you have to create an object on the heap that doesn't already exist on the heap to do this?
A better option is to take a pointer to a struct as an "out" parameter, use that pointer to store the actual result, then return an int status code indicating success or failure (or a bool if you have a C99 compiler). This would look something like:
int give_me_a_struct(MyStruct*);
MyStruct result;
if (give_me_a_struct(&result)) {
// yay! we got a result!
}
else {
// boo! we didn't get a result!
}
If give_me_a_struct returns zero, it indicates that it did not find the result and the result object was not populated. If it returns nonzero, it indicates that it did find the result and the result object was populated.
C doesn't allow global non-const assignments. So you must do this in a function:
void init() {
NotFoundStruct.x = 0;
NotFoundStruct.y = 0;
}
As for the comparison, C doesn't know how to apply a == operator to a struct. You can overload (redefine) the operator in C++, but not in C.
So to see if a return value is empty, your options are to
Have each function return a boolean value to indicate found or not, and return the struct's values via pointers through the argument list. (eg. bool found = give_me_a_struct(some_input, &thing);)
Return a pointer to a struct, which can be NULL if nothing exists. (eg. MyStruct* thing = give_me_a_struct(some_input);)
Add an additional field to the struct that indicates whether the object is valid.
The third option is the most generic for other cases, but requires more data to be stored. The best bet for your specific question is the first option.
// MyStruct.h
typedef struct _MyStruct {
// fields
} MyStruct;
extern MyStruct NotFoundStruct;
// MyStruct.c
#include "my_struct.h"
MyStruct NotFoundStruct = {0};
But since you can't use the == operator, you will have to find another way to distinguish it. One (not ideal) way is to have a bool flag reserved to indicate validity. That way, only that must be checked to determine if it's a valid instance.
But I think you should consider James's proposed solution instead
In the header:
// Structure definition then
extern MyStruct myStruct;
In the .c that contains global data
struct MyStruct myStruct
{
initialize field 1,
initialize field 2,
// etc...
};
Difference between value parameter and reference parameter ? This question is asked sometime by interviewers during my interviews. Can someone tell me the exact difference that is easy to explain with example? And is reference parameter and pointer parameter are same thing ?
Thanks
Changes to a value parameter are not visible to the caller (also called "pass by value").
Changes to a reference parameter are visible to the caller ("pass by reference").
C++ example:
void by_value(int n) { n = 42; }
void by_ref(int& n) { n = 42; }
void also_value(int const& n); // Even though a reference is used, this is
// semantically a value parameter---though there are implementation
// artifacts, like not being able to write "n = 42" (it's const) and object
// identity (&n here has different ramifications than for by_value above).
One use of pointers is to implement "reference" parameters without using a special reference concept, which some languages, such as C, don't have. (Of course you can also treat pointers as values themselves.)
The main difference is whether the object passed is copied. If it's a value parameter the compiler must generate such code that altering the function parameter inside the function has no effect on the original object passsed, so it will usually copy the object. In case of reference parameters the compiler must generate such code taht all operations are done on the original object being passed.
A pointer is a low-level way of representing a reference, so passing a pointer (by value) is how languages like C typically achieve pass by reference semantics.
The difference is pretty simple: direct parameters are passed by value, and the receiver receives a copy of what is passed; meaning that if the parameter is modified by the receiver, these changes will not be reflected back to the caller. (This is often called, appropriately enough, pass by value, or by copy.
There are basically three kinds of parameters; pointer, reference and direct.
The difference is pretty simple: direct parameters are passed by value, and the receiver receives a copy of what is passed; meaning that if the parameter is modified by the receiver, these changes will not be reflected back to the caller. (This is often called, appropriately enough, pass by value, or bycopy.
Pointers are also passed by value, but rather than sending the actual value, the caller sends the address of the value. This means that by following this pointer, the receiver can modify the argument. Note that changes made to the actual pointer still aren't reflected back to the caller.
The final form, call-by-reference, is sort of a middle ground between these two approaches. Essentially it can be thought of as a pointer that looks like a value.
It is worth mentioning that at the core of it all, parameters are always passed by value, but different languages have different ways of implementing reference semantics (see Kylotans answer).
// Example using C
// bycopy
int multiply(int x, int y) {
return x * y;
}
void multiply_p(int *x, int y) {
*x *= y;
}
int main () {
int i, j, k;
i = 20;
j = 10;
k = multiply(i,j); // k is now 200
multiply_p(&i, k); // i is now 4000 (200 * 20)
return 0;
}
Pseudocode:
Pass by Value:
void setTo4(value) { // value is passed by value
value = 4;
}
int x = 1;
setTo4(x);
// x is still 1
Pass by Reference:
void setTo4(value) { // value is passed by reference
value = 4;
}
int x = 1;
setTo4(x);
// x is 4