Skip to content

Commit effe481

Browse files
author
Tomas Pevny
committed
fixing
1 parent 2156d3e commit effe481

File tree

1 file changed

+49
-45
lines changed

1 file changed

+49
-45
lines changed

docs/src/lectures/lecture_06/lecture.md

Lines changed: 49 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -318,17 +318,19 @@ and the output is used mainly for debugging / inspection.
318318
Language introspection is very convenient for investigating, how things are implemented and how they are optimized / compiled to the native code.
319319

320320
::: note "Reminder `@which`"
321-
Though we have already used it quite a few times, recall the very useful macro `@which`, which identifies the concrete function called in a function call. For example `@which mapreduce(sin, +, [1,2,3,4])`. Note again that the macro here is a convenience macro to obtain types of arguments from the expression. Under the hood, it calls `InteractiveUtils.which(function_name, (Base.typesof)(args...))`. Funny enough, you can call `@which InteractiveUtils.which(+, (Base.typesof)(1,1))` to inspect, where `which` is defined.
321+
Though we have already used it quite a few times, recall the very useful macro `@which`, which identifies the concrete function called in a function call. For example `@which mapreduce(sin, +, [1,2,3,4])`. Note again that the macro here is a convenience macro to obtain types of arguments from the expression. Under the hood, it calls `InteractiveUtils.which(function_name, (Base.typesof)(args...))`. Funny enough, you can call `@which InteractiveUtils.which(+, (Base.typesof)(1,1))` to inspect, where `which` is defined.
322322

323-
Alternatively, you can invest time in learning `Cthulhu.jl` package, which is a tool for inspecting functions called in a function. In other words it will simplify a recursive call of which when one is interested in how internals of some function are implemented.
323+
Alternatively, you can invest time in learning `Cthulhu.jl` package, which is a tool for inspecting functions called in a function. In other words it will simplify a recursive call of which when one is interested in how internals of some function are implemented.
324+
:::
324325

325326
::: note "Effect analysis"
326-
The compiler is analysing the code to automatically infer some properties, which can help it to create more efficient code. This is analysis id called effect analysis and you can execute it yourself using `Base.infer_effects`. For example for our `nextfib` we obtain (on 1.11.1)
327-
```julia
328-
julia> Base.infer_effects(nextfib, (Int,))
329-
(+c,+e,+n,!t,+s,+m,+u,+o,+r)
330-
```
331-
See the documentation for (Base.@assume_effects)[https://docs.julialang.org/en/v1/base/base/#Base.@assume_effects] for details of individual fields.
327+
The compiler is analysing the code to automatically infer some properties, which can help it to create more efficient code. This is analysis id called effect analysis and you can execute it yourself using `Base.infer_effects`. For example for our `nextfib` we obtain (on 1.11.1)
328+
```julia
329+
julia> Base.infer_effects(nextfib, (Int,))
330+
(+c,+e,+n,!t,+s,+m,+u,+o,+r)
331+
```
332+
See the documentation for (Base.@assume_effects)[https://docs.julialang.org/en/v1/base/base/#Base.@assume_effects] for details of individual fields.
333+
:::
332334

333335
### Broadcasting
334336
Broadcasting is not a unique concept in programming languages (Python/Numpy, MATLAB), however its implementation in Julia allows to easily fuse operations. For example
@@ -399,9 +401,9 @@ unstable_pack = [Wolf("1", 1), Wolf("2", 2), Sheep("3", 3)]
399401
@code_typed map(sound, stable_pack)
400402
@code_typed map(sound, unstable_pack)
401403
```
402-
::: info
403-
## Cthulhu.jl
404-
`Cthulhu.jl` is a library (tool) which simplifies the above, where we want to iteratively dive into functions called in some piece of code (typically some function). `Cthulhu` is different from te normal debugger, since the debugger is executing the code, while `Cthulhu` is just lower_typing the code and presenting functions (with type of arguments inferred).
404+
::: info Cthulhu.jl
405+
`Cthulhu.jl` is a library (tool) which simplifies the above, where we want to iteratively dive into functions called in some piece of code (typically some function). `Cthulhu` is different from te normal debugger, since the debugger is executing the code, while `Cthulhu` is just lower_typing the code and presenting functions (with type of arguments inferred).
406+
:::
405407
406408
```julia
407409
using Cthulhu
@@ -468,57 +470,59 @@ The parsed code `p` is of type `Expr`, which according to Julia's help[^2] is *a
468470
[^2]: Help: [`Core.Expr`](https://docs.julialang.org/en/v1/base/base/#Core.Expr)
469471
470472
::: info "Symbol type"
471-
When manipulations of expressions, we encounter the term `Symbol`. `Symbol` is the smallest atom from which the program (in AST representation) is built. It is used to identify an element in the language, for example variable, keyword or function name. Symbol is not a string, since string represents itself, whereas `Symbol` can represent something else (a variable). An illustrative example[^3] goes as follows.
472-
```julia
473-
julia> eval(:foo)
474-
ERROR: foo not defined
473+
When manipulations of expressions, we encounter the term `Symbol`. `Symbol` is the smallest atom from which the program (in AST representation) is built. It is used to identify an element in the language, for example variable, keyword or function name. Symbol is not a string, since string represents itself, whereas `Symbol` can represent something else (a variable). An illustrative example[^3] goes as follows.
474+
```julia
475+
julia> eval(:foo)
476+
ERROR: foo not defined
475477
476-
julia> foo = "hello"
477-
"hello"
478+
julia> foo = "hello"
479+
"hello"
478480
479-
julia> eval(:foo)
480-
"hello"
481+
julia> eval(:foo)
482+
"hello"
481483
482-
julia> eval("foo")
483-
"foo"
484-
```
485-
which shows that what the symbol `:foo` evaluates to depends on what – if anything – the variable `foo` is bound to, whereas "foo" always just evaluates to "foo".
484+
julia> eval("foo")
485+
"foo"
486+
```
487+
which shows that what the symbol `:foo` evaluates to depends on what – if anything – the variable `foo` is bound to, whereas "foo" always just evaluates to "foo".
486488
487-
Symbols can be constructed either by prepending any string with `:` or by calling `Symbol(...)`, which concatenates the arguments and create the symbol out of it. All of the following are symbols
488-
```julia
489-
julia> :+
490-
:+
489+
Symbols can be constructed either by prepending any string with `:` or by calling `Symbol(...)`, which concatenates the arguments and create the symbol out of it. All of the following are symbols
490+
```julia
491+
julia> :+
492+
:+
491493
492-
julia> :function
493-
:function
494+
julia> :function
495+
:function
494496
495-
julia> :call
496-
:call
497+
julia> :call
498+
:call
497499
498-
julia> :x
499-
:x
500+
julia> :x
501+
:x
500502
501-
julia> Symbol(:Very,"_twisted_",:symbol,"_definition")
502-
:Very_twisted_symbol_definition
503+
julia> Symbol(:Very,"_twisted_",:symbol,"_definition")
504+
:Very_twisted_symbol_definition
503505
504-
julia> Symbol("Symbol with blanks")
505-
Symbol("Symbol with blanks")
506-
```
507-
Symbols therefore allows us to operate with a piece of code without evaluating it.
506+
julia> Symbol("Symbol with blanks")
507+
Symbol("Symbol with blanks")
508+
```
509+
Symbols therefore allows us to operate with a piece of code without evaluating it.
508510
509-
In Julia, symbols are "interned strings", which means that compiler attaches each string a unique identifier (integer), such that it can quickly compare them. Compiler uses Symbols exclusively and the important feature is that they can be quickly compared. This is why people like to use them as keys in `Dict`.
511+
In Julia, symbols are "interned strings", which means that compiler attaches each string a unique identifier (integer), such that it can quickly compare them. Compiler uses Symbols exclusively and the important feature is that they can be quickly compared. This is why people like to use them as keys in `Dict`.
512+
:::
510513
511514
[^3]: An [example](https://stackoverflow.com/questions/23480722/what-is-a-symbol-in-julia) provided by Stefan Karpinski.
512515
513516
::: info "Expressions"
514-
From Julia's help[^2]:
517+
From Julia's help[^2]:
515518
516-
`Expr(head::Symbol, args...)`
519+
`Expr(head::Symbol, args...)`
517520
518-
A type representing compound expressions in parsed julia code (ASTs). Each expression consists of a head `Symbol` identifying which kind of expression it is (e.g. a call, for loop, conditional statement, etc.), and subexpressions (e.g. the arguments of a call).
519-
The subexpressions are stored in a `Vector{Any}` field called args.
521+
A type representing compound expressions in parsed julia code (ASTs). Each expression consists of a head `Symbol` identifying which kind of expression it is (e.g. a call, for loop, conditional statement, etc.), and subexpressions (e.g. the arguments of a call).
522+
The subexpressions are stored in a `Vector{Any}` field called args.
520523
521-
The expression is simple yet very flexible. The head `Symbol` tells how the expression should be treated and arguments provide all needed parameters. Notice that the structure is also type-unstable. This is not a big deal, since the expression is used to generate code, hence it is not executed repeatedly.
524+
The expression is simple yet very flexible. The head `Symbol` tells how the expression should be treated and arguments provide all needed parameters. Notice that the structure is also type-unstable. This is not a big deal, since the expression is used to generate code, hence it is not executed repeatedly.
525+
:::
522526
523527
## Construct code from scratch
524528
Since `Expr` is a Julia structure, we can construct it manually as we can construct any other structure

0 commit comments

Comments
 (0)