Advertisement
Guest User

Untitled

a guest
Dec 9th, 2019
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.00 KB | None | 0 0
  1. COP4020 Final Study Guide (Based on HW4 / HW5)
  2.  
  3. _______________________________________________
  4.  
  5. Does Erlang use static scoping?
  6. Yes, because it makes closures*.
  7.  
  8. What kind of type checking does Erlang use?
  9. It uses dynamic type checking.
  10.  
  11.  
  12.  
  13. HW4: concat
  14. Write a function 'concat/1' whose type is given:
  15.  
  16. -spec concat(Lists :: [[T]]) -> [T].
  17.  
  18. which takes a list of lists, Lists, and returns a
  19. list that contains all of the inner lists concatenated
  20. together, in order.
  21.  
  22. %start%
  23. -module(concat).
  24. -export([concat/1]).
  25.  
  26. concat([]) -> [].
  27. concat([Head|Rest]) -> Head ++ concat(Rest).
  28. %end%
  29.  
  30.  
  31.  
  32. HW4: salesdata/substaddr
  33. Given two record types, defined in salesdata.hrl:
  34.  
  35. -record(store, {address :: string(), amounts :: [integer()]}).
  36. -record(group, {gname :: string(), members :: [salesdata:salesdata()]}).
  37.  
  38. where the type salesdata() is defined:
  39.  
  40. %start%
  41. -module(salesdata).
  42. -include(salesdata.hrl").
  43. -export_type([salesdata/0]).
  44.  
  45. -type salesdata() :: #store{} | #group{}.
  46. %end%
  47.  
  48. write a function:
  49.  
  50. -spec substaddr(SD :: salesdata:salesdata(), New :: string(), Old :: string()) -> salesdata:salesdata().
  51.  
  52. that takes a sales data record 'SD',
  53. two strings 'New' and 'Old', and returns a sales
  54. data record who's identical to SD except that all
  55. addresses with the value 'Old' are replaced with 'New'
  56.  
  57. For this problem, since Erlang does not currently
  58. permit type imports, you pattern match for record data
  59. when defining the functions for substaddr:
  60.  
  61. %start%
  62. -module(substaddr).
  63. -export([substaddr/3]).
  64. -include("salesdata.hrl").
  65. -import(salesdata, [store/2, group/2]).
  66.  
  67. -spec substaddr(SD :: salesdata:salesdata(), New :: string(), Old :: string()) -> salesdata:salesdata().
  68.  
  69. substaddr(#store{address = Addr, amounts = Amts}, New, Old) ->
  70. #store{address = if Addr =:= Old -> New;
  71. true -> Addr
  72. end,
  73. amounts = Amts};
  74. substaddr(#group{gname = Name, members = Mems}, New, Old) ->
  75. #group{gname = Name,
  76. members = lists:map(fun (SD) -> substaddr(SD, New, Old) end, Mems)}.
  77. %end%
  78.  
  79. Assign each field to a variable, then return a record,
  80. assign each field in the new record according to the
  81. proper logic
  82.  
  83.  
  84.  
  85. HW4: count_matching
  86. Write a tail-recursive function:
  87.  
  88. -spec count_matching (Pred::fun((T) -> boolean()), Lst::list(T)) -> non_neg_integer().
  89.  
  90. that takes a predicate, Pred, and a list, Lst, and
  91. returns the number of elements in Lst that satisfy
  92. Pred.
  93.  
  94. %start%
  95. -module(count_matching).
  96. -export([count_matching/2,loop/3]).
  97. -spec count_matching (Pred::fun((T) -> boolean()), Lst::list(T)) -> non_neg_integer().
  98.  
  99. count_matching(Pred, Lst) ->
  100. loop(Pred,Lst,0).
  101. -spec loop(Pred :: fun((T) -> boolean()), Lst :: list(T), Acc :: non_neg_integer()) -> integer().
  102. loop(_P,[],Acc) ->
  103. Acc;
  104. loop(P, [X|Xs], Acc) ->
  105. loop(P, Xs, Acc + (case P(X) of
  106. true -> 1;
  107. false -> 0
  108. end)).
  109. %end%
  110.  
  111. _________________________________________________
  112.  
  113. HW5: mapInside
  114. Correctly implement the following function:
  115.  
  116. -spec mapInside(F::fun((T) -> R), Llt::list(list(T))) -> list(list(R)).
  117.  
  118. which for all types T & R, takes a function F from
  119. T to R, and a list of lists, Llt, who consist of lists
  120. of type T... and returns a list of lists whose
  121. elements are the lists that come from mapping F over
  122. lists of type T inside Llt in order
  123.  
  124. mapInside(F, Llt) -> foldr(fun(Ls, Res) -> [map(F,Ls)|Res] end, [], Llt).
  125.  
  126.  
  127.  
  128. HW5: FREE AND BOUND IDENTIFIERS
  129. Considering the following expression:
  130.  
  131. H(fun(X,Y) -> K(foo(bar({the_fun, fun(A,H) -> minus (A,4020) end}))) end; K)
  132.  
  133. List the set of all identifiers that occur free
  134. {H,K,foo,bar,minus}.
  135.  
  136. NOTE: 'the_fun' is an atom, not an identifier. ALSO,
  137. X & Y are not used, only declared. They do not occur
  138. either free or bound.
  139.  
  140. List the set of all identifiers that occur bound
  141. {A}.
  142.  
  143. NOTE: minus, foo, bar are not declared in the
  144. expression, and are thus free and not bound.
  145. X & Y are not used, only declared. They do not occur
  146. either free or bound.
  147. While H is used in the expression, the use is not in
  148. the scope of the declaration of H as a formal param,
  149. thus the use of H is a free (not bound) occurance.
  150.  
  151.  
  152.  
  153. HW5: MORE ON FREE AND BOUND IDENTIFIERS
  154. Consider the following expression:
  155.  
  156. P(foo(Q(map(fun (E) -> bar(P, Q, P(Q(E)), F) end,
  157. [zero, false, 1, fun(F,G) -> fun(X) -> F(F(X)) end end]))))
  158.  
  159. List the set of all identifiers that occur free
  160. {P,Q,foo,map,bar,F}.
  161.  
  162. NOTE: zero and false are atoms, not identifiers. G
  163. is not used at all, only declared. It does not occur
  164. free or bound.
  165.  
  166. List the set of all identifiers that occur bound
  167. {E,F,X}.
  168.  
  169. NOTE: zero and false are atoms, not identifiers. G
  170. is not used at all, only declared. It does not occur
  171. free or bound.
  172.  
  173.  
  174.  
  175. HW5: Scope rules & concepts
  176. Suppose a programming language has a way to create
  177. function values at runtime, like Erlang does. Explain
  178. how the semantics of function values can tell you
  179. about whether that language has static or dynamic
  180. scoping for variable names?
  181.  
  182. Answer: If the language makes closures when it
  183. creates function values at runtime, then it has static
  184. scoping, because closures are designed to record
  185. the surrounding environment of a function value for
  186. static scoping.
  187.  
  188. **What is a closure?
  189.  
  190.  
  191. If a language makes closures for function values that
  192. are created at runtime, then with respect to the
  193. closure expression itself, what kind of identifiers
  194. that occur within the text of the function closure
  195. expression's code does it need to remember values for:
  196. Free identifiers or bound identifiers?
  197.  
  198. Answer: Free identifiers, as those are not defined by
  199. declarations within the code.
  200.  
  201.  
  202. Is static scoping more useful for variables than
  203. dynamic scoping? Explain why (or why not)
  204.  
  205. Answer: Yes, static scoping is more useful, because
  206. it allows you to understand a functional abstraction
  207. locally, where it is written, and to have that
  208. understanding be valid throughought the execution of
  209. the program (unlike with dynamic scoping). Static
  210. scoping also supports techniques like currying
  211. functions and static type checking.
  212.  
  213. How are exception handlers in Java (or C# or C++)
  214. scoped? Statically or dynamically?
  215.  
  216. Answer: They are scoped dynamically, because when an
  217. exception is thrown, the most recent active handler
  218. for that exception is executed.
  219.  
  220.  
  221.  
  222. HW5: TYPE CHECKING
  223. An example of an expression in Erlang that generates
  224. a type error:
  225.  
  226. Answer: 3 + atom.
  227.  
  228. Which type of type checking allowers the programmer
  229. more flexibility? Static or Dynamic?
  230.  
  231. Answer: Dynamic type checking. Static checking, due
  232. to it's conservative nature, will prevent some
  233. programs that would not (dynamically) encounter a
  234. type error from executing, such as the one below.
  235.  
  236. Give an example of an expression (in Erlang) or
  237. program that will run without a type error that
  238. would not type check if it were translated into
  239. Haskell
  240.  
  241. Answer:
  242.  
  243. One: Haskell doesn't allow heterogeneous lists, while
  244. Erlang does.
  245.  
  246. (Okay) in Erlang: [1, true, fun(X) -> X+4020 end]
  247. (Not Okay) Haskell equivalent: [1, True, (\x->x+4020])]
  248. - is a type error
  249.  
  250. Two: Haskell comparisons using are restricted to work
  251. with the same type on both sides. But not in Erlang.
  252.  
  253. (Okay) in Erlang: (atom == 3) andalso ("string" < 5)
  254. - which evaluates to false
  255. (Not Okay) Haskell equivalent: ("atom" == 3) && ("string" < 5)
  256. - is a type error
  257.  
  258. Three: Haskell function arguments are monomorphic,
  259. a restriction of the Hindley-Milner type system it
  260. uses. Since Erlang is dynamically typed, this is fine,
  261. as the identity function can be applied to arguments
  262. of different types:
  263.  
  264. (Okay) in Erlang: (fun(F) -> {F(3), F(atom)} end)(fun(X) -> X end)
  265. (Not Okay) Haskell equivalent: (\f -> (f 3, f "atom)) (\x -> x)
  266. - is a type error
  267.  
  268. **What does monomorphic mean?
  269.  
  270. In Erlang, does the representation of every value need
  271. to be encoded in a way that the runtime system can
  272. tell what its type is during each program's exe?
  273.  
  274. Answer: Yes, that is needed for dynamic type checking
  275. and for the execution of the BIFs that do type tests
  276. at runtime, like is_number, is_atom, and is_pid
  277.  
  278. **What are BIFs?
  279. BIFs are the functions in Erlang that do tasks which
  280. are impossible to program (in Erlang) such as turning
  281. a list into a tuple.
  282.  
  283.  
  284. In Haskell, does the representation of every value
  285. need to be encoded in a way that the runtime system
  286. can tell what its type is during each program's exe?
  287.  
  288. Answer: No, type checking is all done before runtime,
  289. and there is no way to get the runtime type of a
  290. value at runtime. Type dictionaries are passed at
  291. runtime for code whose type needs values of a
  292. particular type class, but this does not apply generally.
  293.  
  294.  
  295. What kind of problems can be solved using a stateless
  296. server in Erlang?
  297.  
  298. Answer: A stateless server can be used when the
  299. responses to messages do not depend on earlier
  300. messages or responses; that is when no history
  301. is needed to respond to messages.
  302.  
  303. HW5: MODULES, DATA ABSTRACTION, ENCAPSULATION (info hiding)
  304.  
  305.  
  306. *
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement