Practical Julia: A Hands-On Introduction for Scientific Minds - podcast episode cover

Practical Julia: A Hands-On Introduction for Scientific Minds

May 14, 202525 min
--:--
--:--
Download Metacast podcast app
Listen to this episode in Metacast mobile app
Don't just listen to podcasts. Learn from them with transcripts, summaries, and chapters for every episode. Skim, search, and bookmark insights. Learn more

Episode description

This Book provides a comprehensive introduction to the Julia programming language, designed particularly for scientists and engineers. It covers foundational concepts like data types, operators, control flow (loops and conditionals), and functions, along with more advanced topics such as multiple dispatch, metaprogramming, plotting, and working with various data structures. The text also explores Julia's application in specific scientific domains, including physics simulations (using Oceananigans and DifferentialEquations), statistics (with DataFrames and StatsPlots), biology (agent-based modeling), and signal/image processing, highlighting the language's composability and efficiency for numerical and scientific computing. It also touches on topics like unit handling (Unitful), symbolic mathematics (Symbolics and SymPy), and techniques for concurrency and parallelism.

You can listen and download our episodes for free on more than 10 different platforms:
https://linktr.ee/cyber_security_summary

Get the Book now from Amazon:
https://www.amazon.com/Practical-Julia-Lee-Phillips/dp/1718502761?&linkCode=ll1&tag=cvthunderx-20&linkId=79a161e0382d545ef973c1dc5f393d57&language=en_US&ref_=as_li_ss_tl


Discover our free courses in tech and cybersecurity, Start learning today:
https://linktr.ee/cybercode_academy

Transcript

Speaker 1

Welcome to the deep dive. You send us practical Julia dot pdf, and we're going to explore why this language, Julia is making ways, especially in science and tech.

Speaker 2

Exactly. Our mission really is to pull out the key ideas about what makes Julia special and why it could be a well, a really useful tool for you.

Speaker 1

Think of this as the quick guide to Julia's main straints. We want to hit the highlights what really sets it apart without getting totally bogged down in every little command.

Speaker 2

Yeah, keep it focused.

Speaker 1

It's got quite an origin story actually came out of MIT back in twenty twelve. The creators were they jokingly call themselves greedy, greedy in what way they wandered it all in one language. They're the ease of use you get from something like Python.

Speaker 2

Uh huh, the interactive feel, right yeah.

Speaker 1

But also the raw speed, the high performance you usually need languages like C or Fortran four.

Speaker 2

Okay, so the best of both worlds. And yeah, if you've used interactive environments Pythons, repl matt Lab, Octave, some parts of Julia will feel pretty familiar, like.

Speaker 1

Typing a command and getting an answer straight.

Speaker 2

Away exactly that and defining variables on the fly, not always needing to specify their type beforehand. That feels comfortable, right it does.

Speaker 1

But okay, let's pivot slightly because this is where Julia gets well, really unique, isn't it?

Speaker 2

Definitely? What makes it stand out, especially for scientists and engineers, is this thing called multiple dispatch.

Speaker 1

Multiple dispatch sounds technical, it is a bit, but the concept is key.

Speaker 2

It's powered by Julia's type system, which is very sophisticated, and it's this feature, combined with the interactivity and the speed that's driving its adoption.

Speaker 1

So what does multiple dispatch do differently?

Speaker 2

Okay, so imagine you want to add two things in many languages, the decision of how to add them depends only on the type of the first thing. Right, With multiple dispatches, Julia looks at the types of all the things involved. So adding an integer and a floating point number might use a different internal method than adding two integers or adding an integer in a fraction.

Speaker 1

Ah. So it picks the most specific recipe based on everything you give it precisely.

Speaker 2

That makes it incredibly flexible and crucially very fast when you're dealing with all the different kinds of data you find in scientific computing.

Speaker 1

Interesting. Okay, so the material you sent practical Julia. How does it structure this give us the roadmap?

Speaker 2

Sure, it starts naturally with the basics, setting things up, the syntax, the fundamental building.

Speaker 1

Blocks, the usual starting point. Yep.

Speaker 2

Then it moves into organizing code, modules, packages, then visualization which is huge.

Speaker 1

Plotting yeah, always important, Then.

Speaker 2

Different ways to store data collections. It even gets into metaprogramming.

Speaker 1

Whoa code that writes code.

Speaker 2

Essentially, Yeah, pretty advanced stuff. Then things like diagrams, animations, the type sister itself in detail, handling physical units. Wow, okay, And finally it shows Julia in action across different fields physics, biology, stats, math, signal processing, image analysis, even parallel computing.

Speaker 1

So it covers a lot of ground.

Speaker 2

It really does, speaks volumes about Julia's versatility. Actually, following this structure should give you a really solid grasp from the core ideas out to the more specialized stuff.

Speaker 1

All right, let's dive into that core. Then, getting started, the book talks about the r EPL that interactive command line.

Speaker 2

Uh huh, the read evil print loop.

Speaker 1

Right, and it has different modes, like a normal mode than a shell mode.

Speaker 2

Yeah, you hit a semicolon, and you're basically at your system's command line right inside Julia. Super handy, and.

Speaker 1

A package mode too with a bracket.

Speaker 2

That's right, And that integrated package system is honestly a bit of a game changer. Oh so well, finding, installing and managing external libraries, you know, extra tools people have written can be a real nightmare in some ecosystem.

Speaker 1

Oh yeah, dependency hell exactly.

Speaker 2

That Julia's built in package manager, accessed with that Hall is designed to make that whole process much much smoother. It's like having the app store right there in the language.

Speaker 1

Okay, that sounds genuinely useful. So after the environment, it's the basic data types, right, the absolute fundamentals yep.

Speaker 2

Numbers, integers, floating point, decimals, even fractions, rationals, and things like infinity and logic, true and false, true and false. And the book points out something called short circuiting for nd A and D.

Speaker 1

And ore, meaning it stops evaluating early.

Speaker 2

Exactly if you have condition one and condition two and condition one is false, Julia doesn't even bother checking condition two because the whole thing has to be false. Saves time, prevents potential errors.

Speaker 1

Smart, okay, and it differentiates between zero mb it does checks if the values are equal, So five equals five point zero would be true because five equals five point zero numerically right, But.

Speaker 2

Checks for identity. Are they the exact same thing and memory the same type? So five equals five point zero is false. One's an integer, one's afloat.

Speaker 1

Got it value versus identity, Like checking if two coins have the same value versus checking if they're the exact same coin.

Speaker 2

That's a perfect analogy.

Speaker 1

Yeah, okay, Next up collections putting data together a raise.

Speaker 2

First, arrays are fundamental. They can be simplests vectors or tables like matrices or even higher dimensional things.

Speaker 1

And you access elements with square.

Speaker 2

Bracket yep, square brackets. And it's important to note you can get a single element with one index, or a whole slice like a row or column using a colon red.

Speaker 1

And you need the right number of indices for your array, right, like two indices for a matrix spot on.

Speaker 2

Using the wrong number will give you an error. Understanding how to index and slice arrays efficiently is crucial for numerical work.

Speaker 1

Then strings text data defined with double quotes double quotes.

Speaker 2

Yeah, the booknotes they're kind of like lists of characters, but with a key difference. They're immutable.

Speaker 1

Immutable meaning you can't change them once they're created.

Speaker 2

Exactly. You can't just swap out one character in the middle of an existing string, You'd have to create a new.

Speaker 1

One, okay. And joining strings uses the asterisker.

Speaker 2

Yep concatenates to them. And you can check for characters using in or for substrings using the a cursin function.

Speaker 1

And there's a warning about.

Speaker 2

Unicode, because Julia handles Unicode characters, which can take up different numbers of bytes. Trying to access a specific bite might land you in the middle of a character, causing a string index error. Just something to be aware of.

Speaker 1

And for multiline text, triple quotes like this very handy. Okay, what about ranges you mentioned eight point two point one.

Speaker 2

Right, ranges define sequences? Eight point two point one means start at eight step by Naze's two, so go down, stop when you get to one, or pass it. So eight six four to two super useful in loops.

Speaker 1

Speaking of loops, the four loop you can use in or or even that fancy symbol uh huh, I'll work.

Speaker 2

For iterating, and you can nest them easily even with a compact comma syntax. For simple cases, loops, work of arranges, arrays, all sorts.

Speaker 1

Of a collections, gotcha tooples are mentioned too.

Speaker 2

Parentheses immutable exactly like lists, you can't change defined with and the in operator works for checking membership and collections and checks for non membership. Ranges are memory efficient too. They don't store every number, just the start, step and end right.

Speaker 1

That makes sense, okay. Let's talk functions, reusable blocks of code.

Speaker 2

Defined with the function keyword pretty standard. The key concept the book emphasizes here is.

Speaker 1

Scope scope, meaning where variables live.

Speaker 2

Pretty much, variables inside a function are typically local to that function. They don't usually mess with variables of the same name outside the funder totally well. The book mentions a nuance with loops, specifically, if you're running code from a file and you use a variable inside a loop that has the same name as a global variable outside, Julia might warn you about potential shadowing or unintended modification. It's a helpful safety check, okay.

Speaker 1

And functions can change their inputs, there's a naming convention.

Speaker 3

Yes.

Speaker 2

Functions that modify their arguments often end with an exclamation mark like push to add to an array or pop to remove.

Speaker 1

So the inna day is a warning sign. This might change your data exactly.

Speaker 2

It's a really useful convention. Contrast that with mutable types like strings, where operations always create new strings makes sense.

Speaker 1

Anonymous functions are covered too little one liners yep.

Speaker 2

Using the syntax stores great for quick operations and function composition. Combining functions plus do blocks?

Speaker 1

What do blocks for?

Speaker 2

They're clean? Way to pass a multiline anonymous function to another function makes the code much more readable when a function takes another function as an argument, which happens a lot in Julia.

Speaker 1

Interesting. Okay. Scaling up modules and packages for bigger.

Speaker 2

Projects, right, You use using or import to bring code from other modules into your current scope. The book gives examples like linear algebra or random from the standard library.

Speaker 1

Is there a difference between using and import?

Speaker 2

There is a subtle one. Using module brings all exported names into your name space, while import module only brings the module name itself, so you have to write module dot, function name dot, import module dot function one, function two is also possible. Using is more common for interactive use. Import can be clearer in large projects.

Speaker 1

Got it and this ties back to the package manager in the RPA.

Speaker 2

Absolutely, that's where you add these external packages, and the book highlights the project dot tom l and manifest dot tom l file.

Speaker 1

Those are the files that tract dependencies exactly.

Speaker 2

Project dot com lists your direct dependencies, and manifest dot com records the exact versions of all dependencies, including dependencies of dependencies used in your project. This is crucial for reproducibility. Anyone else or you later on can recreate the exact environment no more dependency.

Speaker 1

Hell, that sounds incredibly valuable for collaboration and just sanity. How do you find these packages?

Speaker 2

GitHub is the main place. The book suggests searching GitHub and adding language Julia to your search query to narrow it down.

Speaker 1

Good tip and documentation.

Speaker 2

There's a central place pkg d D three dot julia lang dot org, which often hosts documentation for many registered packages.

Speaker 1

Excellent okay, visualization, you said it was huge. The plos package.

Speaker 2

Plots dot jl is the go to metapackage doesn't do the drawing itself. It uses different back ends. Gr is the default. It's fast and usually just work, but you can install and use others if needed.

Speaker 1

And you just use plot often. Yeah.

Speaker 2

Plot xy is the basic idea, and if you want to add to an existing plot, you use plot with the exclamation mark.

Speaker 1

Again ah, Modifying the plot object makes sense, and customization labels legends all there.

Speaker 2

You can set labels, control the legend position legends on top left, give it a title, legend title, change line styles, LS, line widths, LW, markers, colors, lots of options.

Speaker 1

What about math formulas in plots?

Speaker 2

That's where latex strings comes in. You just put an L before a string like L alpha plus beta and plots with the right back end will render it as proper math using latex really nice for technical plots.

Speaker 1

Very cool and more complex plots. Contours heat maps YEP.

Speaker 2

Contour heat map surface plots are mentioned and arranging multiple plots together.

Speaker 1

How does that work?

Speaker 2

You can use the at layout macro to define a grid structure and then pass multiple plot objects to the plot function. Makes creating figures with subplots pretty straightforward.

Speaker 1

Okay, Moving beyond rays and strings. Other collection types dictionaries.

Speaker 2

YEP, dicked for key value pairs like a Python dictionary or a hash map. You look up values using keys and the sets set for unordered collections of unique elements useful for membership, testing and operations like intersect to find common elements or union to combine elements.

Speaker 1

Okay, and structs.

Speaker 2

Structs let you define your own custom composite data types. You bundle related data fields together. Think of defining a point type with x and y fields.

Speaker 1

And named tuples like tuples, but.

Speaker 2

Each element has a name, so instead of accessing my tupule one, you might access my nametuple dot x makes code more readable.

Speaker 1

So lots of tools for organizing data. Let's circle back to a raise for a bit more advanced concepts.

Speaker 2

Definitely, you can create arrays using functions like comprehensions, which are a very concise way to build arrays based on loops and conditions. Think I two for i in one point five.

Speaker 1

Ah list comprehensions from Python.

Speaker 2

But for arrays exactly, there's also repeat and fill fill value DIMS creates an array where every element is the exact same object in memory. If that object is mutable, changing one changes them all.

Speaker 1

Ooh tricky. What about repeat.

Speaker 2

BP actually copies the elements, so it behaves more like you might initially expect good distinction to know.

Speaker 1

And helper functions like zeros and ones yep.

Speaker 2

Quickly create a rays filled with zeros or ones super common and reshape lets you change the dimensions of an array without changing the data itself.

Speaker 1

Useful. What about numerical operations combining arrays?

Speaker 2

You can concatenate arrays vertically using semicolones AB or horizontally using spaces AB.

Speaker 1

Logical indexing using true false.

Speaker 2

Yeah, this is powerful. If you have an array A and a boolian array B of the same size, AB gives you only the elements of A where the corresponding element in B is true.

Speaker 1

Great for filtering and matrix stuff transpose multiplications.

Speaker 2

The single quote gives you the joint complex conjugate transpose, which is just the transpose for real matrices. Standard matrix multiplication.

Speaker 1

Is just a okay. And iterating enumerate and zip.

Speaker 2

Enumerate collection gives you pairs of index value as you loop. ZIP call one, call two gives you pairs of value one value two from each collection.

Speaker 1

Very useful, and pairs for dictionary.

Speaker 2

Peirs iterates through key value pairs. The book also warns about mixing up the iteration number from enumerate with say the character index in a string, especially with unicode. They aren't always the same.

Speaker 1

Good point. Okay, this feels like we're getting into some really powerful features now, functions, metaprogramming errors.

Speaker 2

Yeah, this is where Julia really starts to flex its muscles. Vargs. For instance, using its in a function definition lets it accept any number of arguments like printal, NBC exactly. Keyword arguments are also common, letting you pass optional arguments by name like plot x, y, line style dot. There's even a concise syntax if the keyword is just a variable name.

Speaker 1

And splatting illy guy in a call. Right.

Speaker 2

If you have arguments in a tuple or dictionary, you can splat them into a function call. My funk ARGs passes elements of the tupple ARBs as individual arguments. For dictionaries with symbol keys, you use myfunk quarks.

Speaker 1

Handy string interpolation with docker yep.

Speaker 2

Variable name is expression embeds values directly in strings, and raw strings are useful if you have lots of backslashes or dollar signs you don't want.

Speaker 1

Interpreted operators are functions. You can define your.

Speaker 2

Own yes plus thalk. They're all just functions, and you can define your own custom infix operators, though you need to follow rules about allowed characters and precedents, which are in the Julida docs.

Speaker 1

Higher order functions, map, filter.

Speaker 2

Reduce standard functional programming tools. Map applies a function to each element, Filter keeps elements based on a condition. Reduce combines elements using a function. The book notes to be careful with reduce and non associated operators like division.

Speaker 1

The order matters and do blocks pop up again here?

Speaker 2

Yep? Because map, filter, etc. Often take functions as arguments. Do blocks make the syntax cleaner for multiline function arguments?

Speaker 1

Okay?

Speaker 3

Symbol type symbols some name are like efficient unique strings, often used internally or for things like dictionary keys or keyword arguments like we saw in plotting attributes line style.

Speaker 1

Dot dash right and then metaprogramming code about code.

Speaker 2

This is advanced but powerful. You can capture Julia code as data using quote, dot end or race. This creates an EXPRUNO object representing the code structure.

Speaker 1

And you can manipulate that structure.

Speaker 2

You can, and then you can evaluate it using Evil, though the book rightly warns to use Evil carefully. You can even write functions that programmatically create variables.

Speaker 1

And macros build on this at macro.

Speaker 2

Name macros are functions that run at parse time. They take code expressions as input and return new code expressions, which then replace the macro call. It's like programmable copy paste, but much smarter.

Speaker 1

What are they used for? Things?

Speaker 2

Simplifying syntax, generating repetitive code, optimizing performance. The book mentions at time and at a lapse for basic timing at b time from benchmark tools for proper benchmarking at code worn type to check type stability crucial for performance, and at FastMATH to allow aggressive, potentially non standard floating point optimizations.

Speaker 1

That at code one type sounds really useful for squeezing out speed.

Speaker 2

It absolutely is. And macros need sometimes to control variable scoping, ensuring variables from the macro's definition don't clash with variables where the macro is used. It's called hygiene.

Speaker 1

Okay, deep stuff. Finally, error handling essential.

Speaker 2

You get stack traces when errors occur, showing the sequence of function calls. You can handle expected errors gracefully using triy dot.

Speaker 1

Catch blocks, and create your own errors.

Speaker 2

YEP using throw, often with specific error types. It domain er if an import value is invalid. Plus warn and error for logging messages without necessarily stopping execution for warnings.

Speaker 1

Right comprehensive error handling. What about graphic beyond plotting diagrams animations.

Speaker 2

The book introduces Luxor dot JL for creating static vector graphics. It's imperative you issue commands like set color, draw circle, draw.

Speaker 1

Text, like programming a drawing step by step exactly.

Speaker 2

The example is a solar system diagram pulling data from NASA, drawing planets, setting colors, dash styles, et cetera.

Speaker 1

Cool and animations.

Speaker 2

That's where Javis dot jl comes in built on Luxor. You define objects and then act on them over time, rotate, translate, scale, dot opacity, then you render the result as a video or gift.

Speaker 1

Examples given and.

Speaker 2

Epicycles animation is mentioned, and a simulation of a vibrating circle visualized with a heat map and polar coordinates. Very neat ways to visualize dynamic processes and interactive plots. Briefly touches on using Pluto notebooks. With the at bind macro, you can link HTML sliders or buttons to Julia variables, making visualizations interactive within the notebook.

Speaker 1

Okay, now the type system we mentioned.

Speaker 2

It's key, absolutely fundamental. Every value in Julia has a type tells you what it is. We have basic numeric types, but also parametric types like rational and sixty four a rational number made from sixty four bit integers.

Speaker 1

And you can check types with isa.

Speaker 2

Ice value type checks if the value is of that type or a subtype. This leads to the type hierarchy, a tree of types sort of Every type has a supertype going all the way up to the root type, and meet types lower down or subtypes. The book even shows visualizing this hierarchy using graph packages. Concrete types are the ones that can actually have instances.

Speaker 1

Can you declare variable types?

Speaker 2

You can globally globalgf dot float sixty four egles one point zero, or locally x dot nt equals five. This x is an assution. Assigning the wrong type will cause an error. Helps catch bugs and sometimes aids performance.

Speaker 1

And defining your own types abstract versus concrete.

Speaker 2

You use abstract type my abstract type end to define concepts and struct my concrete type end for actual data structures with fields, you can specify subtyping relationships using a.

Speaker 1

So struct my concrete type my.

Speaker 2

Abstract precisely, and structs can be parametric too, like structs selips t ND where t could be the number type used for coordinates. You can add constraints using war like selips T, whar T real.

Speaker 1

Very flexible m plot recipes.

Speaker 2

Ah at recipe and at user plot. These let you teach the plots package how to plot your custom types automatically super powerful for integration.

Speaker 1

Makes your own types first class citizens for plotting nice. What about physical units?

Speaker 2

The unit ful dot jl package is fantastic for this. You can create quantities with units using string macros like q U one m.

Speaker 1

And then just do math q two U ones exactly.

Speaker 2

It handles the unit conversions and checks consistency. One meter plus two's would give an air.

Speaker 1

How do you get the number unit back out bestrip.

Speaker 2

Q gives you the numerical value one. In this case, unit q gives you the unit m and convert you cmq converts.

Speaker 1

It deplaying them nicely.

Speaker 2

Latex unit ful of texify dot jl integrates with latexifi reduce properly formatted latex strings for units, with options for how fractions are displayed.

Speaker 1

Plotting handle units automatically.

Speaker 2

Yes, Plots often automatically labels axs with the correct units when you plot unit forul quantities, or you can build labels manually using US strip, unit and latex strings.

Speaker 1

That's incredibly useful for scientific work. Okay, let's talk applications. The book showcases Julia across different fields.

Speaker 2

Oh yeah, a wide range physics, oceananigans for fluid dynamics, differential equations, dot JAIL for solving all kinds of differential equations, pendulum examples, even chaotic systems, platistics, random for random numbers, distributions for statistical distributions to uniform, et cetera. Data frames dot JL for tabular data manipulation, reading, CSVS, filtering, grouping, joining, pivoting like you would in R or.

Speaker 1

Pandas data frame sounds essential.

Speaker 2

It really is for data analysis. Also stats plots for statistical plotting on top of data frames at DF, macro histograms, correlation plots handling missing data covered too. While agents dot JL for agent based modeling. The example is simulating evolution predator prey dynamics where agents move, reproduce, mutate.

Speaker 1

Interact mathematics, symbolic stuff.

Speaker 2

Symbolics DoD JL for computer algebra, define symbolic variables, at variables, create symbolic expressions, differentiate, differential solve equations, solve, substitute value, substitute plot symbolic functions.

Speaker 1

Like MATHEMATICA or maple, but within Julia.

Speaker 2

Kind of yeah. He can even trace regular Julia functions to generate symbolic expressions.

Speaker 1

WOW signal and image.

Speaker 2

Processing signal analysis example, Fouria analysis of audio images, dot JL loading saving, manipulating images, color channels, grayscale image filtering, image minorization, morphological operations like dilation, erosion, feature recognition. It also mentions array views at view for efficient access to submarize offset arrays, and Cartesian indices for easier multidimensional iteration, and.

Speaker 1

Finally, concurrency using multiple cores, threads for multi threading on a single machine, reads macro for loops, threads at spawn for tasks at sync to weight, and distributed for using multiple processes, possibly a cross machines depth p flag to start Julia, PMAT for parallel map at spawn at to run code on specific workers. Performance depends on minimizing communication overhead, So.

Speaker 2

A huge range of applications covered by dedicated packages.

Speaker 1

Absolutely, and this leads to maybe the most important point the book makes near the end, composability. How well all these different packages work together? Ah?

Speaker 2

Right? Because of multiple dispatch and the type system.

Speaker 1

Exactly different packages can interact in ways the original authors might not have even planned. The example given is combining differential equations with Turing dot JL for babilistic programming to do Bayesian inference on parameters of differential equations.

Speaker 2

That sounds incredibly powerful.

Speaker 1

You're not stuck in silos precisely. It revisits that easiest Python fast as four tran idea, but adds composability as maybe the second huge reason Julia is gaining traction. You can build complex solutions by combining specialized tools flexibly. Okay, that's a really compelling picture of Julia. So wrapping up this deep dive based on practical Julia, what are the key takeaways for someone listening?

Speaker 2

I think fundamentally it's this unique blend. You get a language that feels high level and easy to work with, like Python, but it's designed for high performance from the ground up thanks to things like its type system and multiple dispatches, and then you have these really powerful extras like metaprogramming.

Speaker 1

Yeah, that combination seems central, and it's clearly not just theoretical. The application show it's being used for serious work across many technical fields.

Speaker 2

Definitely, it's past the early adopter phase in many areas. The ecosystem is growing fast, it's active, and there are solid packages for doing real science and engineering.

Speaker 1

So if any of those areas we touched on the plotting, the data frames, units with unitful simulations with agents or differential equations, symbolic math, if any of that sounded relevant.

Speaker 2

Then you should definitely dig deeper into those specific packages. The Julia community is generally very welcoming and the documentation is often quite good.

Speaker 1

All right, So here's a final thought to leave you with. We talked a lot about composability. How Julia lets you combine different tools seamlessly.

Speaker 2

Right, the playing well together aspect.

Speaker 1

So think about your own work, your own field. How might you combine existing tools or techniques in Julia in a novel way? Could linking a simulation package with a machine learning library, or a data analysis tool with a visualization framework open up new avenues for discovery or problem solving.

Speaker 2

Hmm. Yeah, that's the exciting potential, isn't it? Using these building blocks and creative combination exactly.

Speaker 1

So keep exploring Julia, check out the community. You might find that its unique approach lets You tackle problems in ways you hadn't considered before

Transcript source: Provided by creator in RSS feed: download file
For the best experience, listen in Metacast app for iOS or Android