A-M baby
This commit is contained in:
parent
764da6cbbb
commit
db842d013d
19005 changed files with 197040 additions and 7 deletions
9
Task/Multiple-distinct-objects/0DESCRIPTION
Normal file
9
Task/Multiple-distinct-objects/0DESCRIPTION
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
Create a [[sequence]] (array, list, whatever) consisting of <var>n</var> distinct, initialized items of the same type. <var>n</var> should be determined at runtime.
|
||||
|
||||
By ''distinct'' we mean that if they are mutable, changes to one do not affect all others; if there is an appropriate equality operator they are considered unequal; etc. The code need not specify a particular kind of distinction, but do not use e.g. a numeric-range generator which does not generalize.
|
||||
|
||||
By ''initialized'' we mean that each item must be in a well-defined state appropriate for its type, rather than e.g. arbitrary previous memory contents in an array allocation. Do not show only an initialization technique which initializes only to "zero" values (e.g. <tt>calloc()</tt> or <tt>int a[n] = {};</tt> in C), unless user-defined types can provide definitions of "zero" for that type.
|
||||
|
||||
This task was inspired by the common error of intending to do this, but instead creating a sequence of <var>n</var> references to the ''same'' mutable object; it might be informative to show the way to do that as well, both as a negative example and as how to do it when that's all that's actually necessary.
|
||||
|
||||
This task is most relevant to languages operating in the pass-references-by-value style (most object-oriented, garbage-collected, and/or 'dynamic' languages).
|
||||
2
Task/Multiple-distinct-objects/1META.yaml
Normal file
2
Task/Multiple-distinct-objects/1META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
note: Object oriented
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
MODE FOO = STRUCT(CHAR u,l);
|
||||
INT n := 26;
|
||||
[n]FOO f;
|
||||
|
||||
# Additionally each item can be initialised #
|
||||
FOR i TO UPB f DO f[i] := (REPR(ABS("A")-1+i), REPR(ABS("a")-1+i)) OD;
|
||||
|
||||
print((f, new line))
|
||||
|
|
@ -0,0 +1 @@
|
|||
A : array (1..N) of T;
|
||||
|
|
@ -0,0 +1 @@
|
|||
A : array (1..N) of T := (others => V);
|
||||
|
|
@ -0,0 +1 @@
|
|||
(1..N => V)
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
a := []
|
||||
Loop, %n%
|
||||
a[A_Index] := new Foo()
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
REM Determine object count at runtime:
|
||||
n% = RND(1000)
|
||||
|
||||
REM Declare an array of structures; all members are initialised to zero:
|
||||
DIM objects{(n%) a%, b$}
|
||||
|
||||
REM Initialise the objects to distinct values:
|
||||
FOR i% = 0 TO DIM(objects{()},1)
|
||||
objects{(i%)}.a% = i%
|
||||
objects{(i%)}.b$ = STR$(i%)
|
||||
NEXT
|
||||
|
||||
REM This is how to create an array of pointers to the same object:
|
||||
DIM objects%(n%), object{a%, b$}
|
||||
FOR i% = 0 TO DIM(objects%(),1)
|
||||
objects%(i%) = object{}
|
||||
NEXT
|
||||
|
|
@ -0,0 +1 @@
|
|||
n.of foo.new
|
||||
|
|
@ -0,0 +1 @@
|
|||
n.of { foo.new }
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
// this assumes T is a default-constructible type (all built-in types are)
|
||||
T* p = new T[n]; // if T is POD, the objects are uninitialized, otherwise they are default-initialized
|
||||
|
||||
//If default initialisation is not what you want, or if T is a POD type which will be uninitialized
|
||||
for(size_t i = 0; i != n; ++i)
|
||||
p[i] = make_a_T(); //or some other expression of type T
|
||||
|
||||
// when you don't need the objects any more, get rid of them
|
||||
delete[] p;
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
// this assumes T is default-constructible
|
||||
std::vector<T> vec1(n); // all n objects are default-initialized
|
||||
|
||||
// this assumes t is a value of type T (or a type which implicitly converts to T)
|
||||
std::vector<T> vec2(n, t); // all n objects are copy-initialized with t
|
||||
|
||||
// To initialise each value differently
|
||||
std::generate_n(std::back_inserter(vec), n, makeT); //makeT is a function of type T(void)
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#include <vector>
|
||||
#include <tr1/memory>
|
||||
using namespace std;
|
||||
using namespace std::tr1;
|
||||
|
||||
typedef shared_ptr<T> TPtr_t;
|
||||
// the following is NOT correct:
|
||||
std::vector<TPtr_t > bvec_WRONG(n, p); // create n copies of p, which all point to the same opject p points to.
|
||||
|
||||
// nor is this:
|
||||
std::vector<TPtr_t> bvec_ALSO_WRONG(n, TPtr_t(new T(*p)) ); // create n pointers to a single copy of *p
|
||||
|
||||
// the correct solution
|
||||
std::vector<TPtr_t > bvec(n);
|
||||
for (int i = 0; i < n; ++i)
|
||||
bvec[i] = TPtr_t(new T(*p); //or any other call to T's constructor
|
||||
|
||||
// another correct solution
|
||||
// this solution avoids uninitialized pointers at any point
|
||||
std::vector<TPtr_t> bvec2;
|
||||
for (int i = 0; i < n; ++i)
|
||||
bvec2.push_back(TPtr_t(new T(*p));
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
foo *foos = malloc(n * sizeof(*foos));
|
||||
for (int i = 0; i < n; i++)
|
||||
init_foo(&foos[i]);
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
user> (take 3 (repeat (rand))) ; repeating the same random number three times
|
||||
(0.2787011365537204 0.2787011365537204 0.2787011365537204)
|
||||
user> (take 3 (repeatedly rand)) ; creating three different random number
|
||||
(0.8334795669220695 0.08405601245793926 0.5795448744634744)
|
||||
user>
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
(make-list n :initial-element (make-the-distinct-thing))
|
||||
(make-array n :initial-element (make-the-distinct-thing))
|
||||
|
|
@ -0,0 +1 @@
|
|||
(loop repeat n collect (make-the-distinct-thing))
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
(map-into (make-list n) #'make-the-distinct-thing)
|
||||
(map-into (make-array n) #'make-the-distinct-thing)
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
auto fooArray = new Foo[n];
|
||||
foreach (ref item; fooArray)
|
||||
item = new Foo();
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
auto barArray = new Bar[n];
|
||||
barArray[] = initializerValue;
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
var
|
||||
i: Integer;
|
||||
lObject: TMyObject;
|
||||
lList: TObjectList<TMyObject>;
|
||||
begin
|
||||
lList := TObjectList<TMyObject>.Create;
|
||||
lObject := TMyObject.Create;
|
||||
for i := 1 to 10 do
|
||||
lList.Add(lObject);
|
||||
// ...
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
var
|
||||
i: Integer;
|
||||
lList: TObjectList<TMyObject>;
|
||||
begin
|
||||
lList := TObjectList<TMyObject>.Create;
|
||||
for i := 1 to 10 do
|
||||
lList.Add(TMyObject.Create);
|
||||
// ...
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
pragma.enable("accumulator")
|
||||
...
|
||||
|
||||
accum [] for _ in 1..n { _.with(makeWhatever()) }
|
||||
|
|
@ -0,0 +1 @@
|
|||
1000 [ { 1 } clone ] replicate
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
program multiple
|
||||
! Define a simple type
|
||||
type T
|
||||
integer :: a = 3
|
||||
end type T
|
||||
|
||||
! Define a type containing a pointer
|
||||
type S
|
||||
integer, pointer :: a
|
||||
end type S
|
||||
|
||||
type(T), allocatable :: T_array(:)
|
||||
type(S), allocatable :: S_same(:)
|
||||
integer :: i
|
||||
integer, target :: v
|
||||
integer, parameter :: N = 10
|
||||
|
||||
! Create 10
|
||||
allocate(T_array(N))
|
||||
|
||||
! Set the fifth one to b something different
|
||||
T_array(5)%a = 1
|
||||
|
||||
! Print them out to show they are distinct
|
||||
write(*,'(10i2)') (T_array(i),i=1,N)
|
||||
|
||||
! Create 10 references to the same object
|
||||
allocate(S_same(N))
|
||||
v = 5
|
||||
do i=1, N
|
||||
allocate(S_same(i)%a)
|
||||
S_same(i)%a => v
|
||||
end do
|
||||
|
||||
! Print them out - should all be 5
|
||||
write(*,'(10i2)') (S_same(i)%a,i=1,N)
|
||||
|
||||
! Change the referenced object and reprint - should all be 3
|
||||
v = 3
|
||||
write(*,'(10i2)') (S_same(i)%a,i=1,N)
|
||||
|
||||
end program multiple
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
func nxm(n, m int) [][]int {
|
||||
d2 := make([][]int, n)
|
||||
for i := range d2 {
|
||||
d2[i] = make([]int, m)
|
||||
}
|
||||
return d2
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
func nxm(n, m int) [][]int {
|
||||
d1 := make([]int, m)
|
||||
d2 := make([][]int, n)
|
||||
for i := range d2 {
|
||||
d2[i] = d1
|
||||
}
|
||||
return d2
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
replicateM n makeTheDistinctThing
|
||||
|
|
@ -0,0 +1 @@
|
|||
mapM makeTheDistinctThing [1..n]
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
do x <- makeTheDistinctThing
|
||||
return (replicate n x)
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
items_wrong := list (10, [])
|
||||
# prints '0' for size of each item
|
||||
every item := !items_wrong do write (*item)
|
||||
# after trying to add an item to one of the lists
|
||||
push (items_wrong[1], 2)
|
||||
# now prints '1' for size of each item
|
||||
every item := !items_wrong do write (*item)
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
items := list(10)
|
||||
every i := 1 to 10 do items[i] := []
|
||||
|
|
@ -0,0 +1 @@
|
|||
i.
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
Foo[] foos = new Foo[n]; // all elements initialized to null
|
||||
for (int i = 0; i < foos.length; i++)
|
||||
foos[i] = new Foo();
|
||||
|
||||
// incorrect version:
|
||||
Foo[] foos_WRONG = new Foo[n];
|
||||
Arrays.fill(foos, new Foo()); // new Foo() only evaluated once
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
List<Foo> foos = new ArrayList<Foo>();
|
||||
for (int i = 0; i < n; i++)
|
||||
foos.add(new Foo());
|
||||
|
||||
// incorrect:
|
||||
List<Foo> foos_WRONG = Collections.nCopies(n, new Foo()); // new Foo() only evaluated once
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
public static <E> List<E> getNNewObjects(int n, Class<? extends E> c){
|
||||
List<E> ans = new LinkedList<E>();
|
||||
try {
|
||||
for(int i=0;i<n;i++)
|
||||
ans.add(c.newInstance());//can't call new on a class object
|
||||
} catch (InstantiationException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static List<Object> getNNewObjects(int n, String className)
|
||||
throws ClassNotFoundException{
|
||||
return getNNewObjects(n, Class.forName(className));
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
var a = new Array(n);
|
||||
for (var i = 0; i < n; i++)
|
||||
a[i] = new Foo();
|
||||
|
|
@ -0,0 +1 @@
|
|||
{x, x, x, x} /. x -> Random[]
|
||||
|
|
@ -0,0 +1 @@
|
|||
{x, x, x, x} /. x :> Random[]
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
a: [1, 2]$
|
||||
|
||||
b: makelist(copy(a), 3);
|
||||
[[1,2],[1,2],[1,2]]
|
||||
|
||||
b[1][2]: 1000$
|
||||
|
||||
b;
|
||||
[[1,1000],[1,2],[1,2]]
|
||||
|
|
@ -0,0 +1 @@
|
|||
VAR a: ARRAY OF T
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
(Foo->new) x $n
|
||||
# here Foo->new can be any expression that returns a reference representing
|
||||
# a new object
|
||||
|
|
@ -0,0 +1 @@
|
|||
map { Foo->new } 1 .. $n;
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
: (make (do 5 (link (new))))
|
||||
-> ($384717187 $384717189 $384717191 $384717193 $384717195)
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
: (mapcar box (range 1 5))
|
||||
-> ($384721107 $384721109 $384721111 $384721113 $384721115)
|
||||
: (val (car @))
|
||||
-> 1
|
||||
: (val (cadr @@))
|
||||
-> 2
|
||||
|
|
@ -0,0 +1 @@
|
|||
[Foo()] * n # here Foo() can be any expression that returns a new object
|
||||
|
|
@ -0,0 +1 @@
|
|||
[Foo() for i in range(n)]
|
||||
|
|
@ -0,0 +1 @@
|
|||
rep(foo(), n) # foo() is any code returning a value
|
||||
|
|
@ -0,0 +1 @@
|
|||
replicate(n, foo())
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#lang racket
|
||||
|
||||
;; a list of 10 references to the same vector
|
||||
(make-list 10 (make-vector 10 0))
|
||||
|
||||
;; a list of 10 distinct vectors
|
||||
(build-list 10 (λ (n) (make-vector 10 0)))
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[Foo.new] * n # here Foo.new can be any expression that returns a new object
|
||||
Array.new(n, Foo.new)
|
||||
|
|
@ -0,0 +1 @@
|
|||
Array.new(n) { Foo.new }
|
||||
|
|
@ -0,0 +1 @@
|
|||
for (i <- (0 until n)) yield new Foo()
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
|c|
|
||||
"Create an ordered collection that will grow while we add elements"
|
||||
c := OrderedCollection new.
|
||||
"fill the collection with 9 arrays of 10 elements; elements (objects)
|
||||
are initialized to the nil object, which is a well-defined 'state'"
|
||||
1 to: 9 do: [ :i | c add: (Array new: 10) ].
|
||||
"However, let us show a way of filling the arrays with object number 0"
|
||||
c := OrderedCollection new.
|
||||
1 to: 9 do: [ :i | c add: ((Array new: 10) copyReplacing: nil withObject: 0) ].
|
||||
"demonstrate that the arrays are distinct: modify the fourth of each"
|
||||
1 to: 9 do: [ :i | (c at: i) at: 4 put: i ].
|
||||
"show it"
|
||||
c do: [ :e | e printNl ].
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package require TclOO
|
||||
|
||||
# The class that we want to make unique instances of
|
||||
set theClass Foo
|
||||
|
||||
# Wrong version; only a single object created
|
||||
set theList [lrepeat $n [$theClass new]]
|
||||
|
||||
# Right version; objects distinct
|
||||
set theList {}
|
||||
for {set i 0} {$i<$n} {incr i} {
|
||||
lappend theList [$theClass new]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue