How to provide all functions associated with a struct in Racket - struct

Is there a way to provide all of the functions associated with a struct without explicitly enumerating them?
For example, if I have foo.rkt:
#lang racket
(provide foo-struct) ; provide all functions, not just the constructor
(struct foo-struct (biz bop))
And then bar.rkt:
#lang racket
(require "foo.rkt")
(define foo (foo-struct 1 2)) ; works just fine
(foo-struct-biz foo) ; is undefined
Is there a way to provide foo-struct-biz and foo-struct-bop (and any other methods associated with the struct) without explicitly listing them?

Thanks to #PetSerAl in the comments, the way to do this is
(provide (struct-out foo-struct))
which will provide all of the methods associated with foo-struct.

Related

Inner constructor in Julia with different name than the struct

I saw this construction in rationals.jl, and I am trying to understand it. I can write
struct Bar
y
global func(x) = new(x)
end
Then if I try:
a = Bar()
I get an error. It is like func is now an inner constructor. And I can actually use it by writing:
a = func(2)
If I remove the keyword global, I can't use this inner constructor anymore. What is going on? Why is global there, and could I use the inner constructor somehow without it (perhaps by qualifying the name)?
How can the inner constructor have a different name than the struct itself? What, in fact, is an inner constructor?
TL/DR
An inner constructor is a method of the struct type (i.e., (::Type{Bar})(...) which has access to new. You can put arbitrary method definitions inside a struct -- there is no technical requirement to only have inner constructors -- but this is only useful in rare cases.
Long version
This is a rare case that the manual doesn't even cover explicitely (and I long didn't know was legal at all). In my understanding, two rules apply:
Inside the struct definition, and only there, you are allowed to use new.
If any inner constructor method is defined, no default constructor method is provided: it is presumed that you have supplied yourself with all the inner constructors you need.
However, nothing requires the inner constructor to be a method of the struct type! Instead you may actually define arbitrary methods.
And then, scoping applies. With a "regular" inner constructor, what you get is a method for Type{Bar}. This requires no global, as the type is present in outer scope.
In your case, without the global, func is local and so there is no constructor accessible at all outside the struct definition. This makes little sense. The global function definition is something that can be useful in rare cases when you want to prevent direct construction of values of you type, but only allow conversion. I have seen this kind of pattern:
struct Baz
Base.reinterpret(::Type{Baz}, ...) = new(...)
end
This adds a (globally available) method to reinterpret, the only entry point to constructing Bazes. Putting it inside the struct is necessary, as at some place you need to create the object and thus require access to new.

What is the difference between Double Colons and Periods?

I am very new to Rust, and the :: operator is new to me. I can tell that :: and . both have their own use cases, and I want to understand on a conceptual level where/why code would use :: vs . or vice versa. Apologies if this is a really basic question!
:: is a path divider. It's mostly used for navigating submodules to express paths that lead to types, traits, modules and stand-alone functions (aka items):
// import everything in the collections module
use std::collections::*;
// specify a fully-qualified type without imports
let map = std::collections::HashMap::new();
// call a stand-alone function
let mut iter = std::iter::once(1);
. is used for navigating data. Specifically, that means accessing members of structs and calling methods:
// call a method
vec.sort();
// access a field of a struct
let bar = foo.bar;
. is really syntactic sugar for :: when talking about (structs, enums, traits):
A call to MyStruct::foo(&my_struct) would be evaluated from my_struct.foo().
You can mostly substitute them when working with what was mentioned above.
Also, :: is used as a "namespace" accessor, for navigatring through rust modules. For example for referring to a method in a nested submodule system:
std::collections::HashMap::get
As a note here, full submodule paths cannot be accessed in any other way with ..

How to create alias to another keyword in rust

Is it possible in Rust to create new keywords that function as an alias to another keyword?
For example, create keyword fun that points to fn and use it as if it were fn:
// somehow alias `fun` to `fn`
fun main() {
println!("Hello, world!")
}
If possible, how would this be accomplished?
If you are looking for an alternative to C's #define, there is nothing that will allow arbitrary words to be used as keywords (which is probably a good thing).
If you are looking to alias a type, Rust has type, which can be used to to rename i64 to int like this: type int = i64;, for example.
Actually, you can do this via procedural macro, since it is just "string transformation".
You cant use crate dtolnay/syn to simplify the work.

Naming struct field ids in Racket when creating struct

I am learning Racket at the moment and would like to know if the following is possible out of the box in Racket. When I create an instance of a class I use the following syntax:
(new Client% [name "John"]
[age 30])
I like the fact that I need to name the field ids when creating an instance of a class. Is there an equivalent when I am creating a struct. I scanned the Racket documentation but could not find anything about naming field ids when creating a struct.
TIA.
If you look at the documentation, you will find that struct creates a constructor for you that takes the initial values of a structure instance as positional arguments. AFAIK there is no built-in support for a "keyword"-like constructor.
Having said that, you can always do something like
(struct client (name age))
(struct client (name age) #:transparent)
(define (new-client #:name n #:age a)
(client n a))
(new-client #:age 20 #:name "me")
to get the usual function with keyword feeling.

Why assign a reference to a struct in go?

I'm having a look at the code at this page:
http://golang.org/pkg/net/http/
And there's one thing I don't understand - at some point, a new structure is created and initialized like this:
client := &http.Client{
CheckRedirect: redirectPolicyFunc,
}
Why use & when creating this structure?
I've also read this blog post and structs are initialized like this:
r := Rectangle{}
What is the difference between both and how should I know which one to use?
The difference is in the type of your variable.
client := &http.Client{
makes client of type *http.Client
while
client := http.Client{
builds a http.Client.
The top one is returning a pointer. It is a Go idiom instead of using new. The second one is just a value object. If you need a pointer use the top.
Check the effective go doc for more about this
http://golang.org/doc/effective_go.html#allocation_new
In object-oriented programming, in order for an object to have dynamic lifetime (i.e. not tied to the current function call), it needs to be dynamically allocated in a place other than the current stack frame, thus you manipulate the object through a pointer. This is such a common pattern that in many object-oriented languages, including Java, Python, Ruby, Objective-C, Smalltalk, JavaScript, and others, you can only deal with pointers to objects, never with an "object as a value" itself. (Some languages though, like C++, do allow you to have "objects as values"; it comes with the RAII idiom which adds some complexity.)
Go is not an object-oriented language, but its ability to define custom types and define methods that operates on that custom type, can be made to work very much like classes and methods. Returning a pointer to the type from the "constructor" function allows the "object" to have a dynamic lifetime.
When we use reference, we use a single item throughout the program runtime. Even if we assign that to a new variable or pass through a function. But when we use value, we make new copies of individual items.
( Reference is not right word according to golang convention. "Address of value" would be more appropriate here https://golang.org/ref/spec#Package_initialization )
An example will make it much clear I hope.
type Employee struct {
ID int
Name string
Address string
}
func main() {
andy := &Employee{}
andy.Name = "Andy"
brad := andy
brad.Name = "Brad"
fmt.Println(andy.Name)
}
The result of this code block would be:
Brad
As we made new variable from it but still referring to same data. But if we use value instead of reference and keep the rest of the code same.
// from
andy := &Employee{}
// to
andy := Employee{}
This time the result would be:
Andy
As this time they both are individual items and not referring to same data anymore.

Resources