 Be gyllud, please? A bit bigger. See if I can do this. So I just had the Windows 10 upgrade happen to me, so I just going to figure out exactly where everything's gone. I think that's about as much as we're going to fit on the screen with this. So I'm going to present Eclipse and the counter-clockwise plug in, which is my personal preferred closure editing environment. I'll show you a few of the workflow things that I do, I find it convenient. I'm not saying it's the best environment, but I quite like Eclipse with counter-clockwise for two reasons. One, I do quite a bit of Java work, and for me I find it's quite handy to have closure and Java all running together in the same IDE. And the second thing is I'm a big fan of Eclipse with a source IDE environment. So I draw into Eclipse and I've stayed with it for most of the time I've been using closure. So I'll just do a quick walk-through. Who's familiar with Eclipse here? Okay, a few. I think it's a fairly standard idea. I don't know at Telly J so well, but I understand a lot of things are fairly similar. So you've got basically we have a nice package explorer at the side, which has all the different projects. You can open projects, close projects, explore all the different files and the directories within the projects. It's got all of the standard Java features. So these are Java packages, Java classes, all of the things you'd expect a Java IDE. What the counter-clockwise does is it transforms this and gives it the extra closure features. So you can see closure files and closure, you know, with closure editors. So this is the closure editor point. With all the syntax highlighting, it's got the rainbow parentheses. It's got auto-propletion functionality. It's got documentation. So if you do the mouseover, it will give you the documentation on all of the things. On this side, it has a namespace browser. So everything which is defined in the current namespace that you're browsing, you can basically see all of these definitions and just jump straight to where they are in the source code. Which is often quite a good way to sort of find your way around a namespace. And of course it has alongside a few other windows that you may find useful, it has a REPL view. So the REPL is just a simple split screen window. You have the output in this part and you have the code here. So normal closure REPL, with syntax highlighting. It's got, you know, you can go backwards and forwards on previous commands. It has Poweredit. So if you're doing, you can quickly select entire blocks. You can take an element, you can raise that 34 to the level above. So you just get 38. All the standard sort of Poweredit commands. I believe that most of the command keystrokes are actually the same as in Emacs or similar to what's in Emacs. It should be relatively familiar to anyone who's used Poweredit. So I think it basically covers most of the things you want out of a closure work bench and an IDA. One thing that I created which I found quite useful is a little tool called CLJUnit which actually does JUnit integration for closure. So what it actually does is it scans the closure namespaces. It picks up anything which has been defined with a death test in closure and it integrates that into the JUnit system. So I thought I'd run a quick demo of that, but this is the CLISC project which is my little fun image generation library. What I can actually do is I can actually just run this as a JUnit test. Now what it's going to do in a second, hopefully. So I think it's probably just downloading something from Maven or something silly like that at the moment. Okay, there we are. So what it's done is it's got this high level test suite but what it's done is it's actually picked out all of the different test functions in the test files and basically ran it as a JUnit test so you can see all the results and the timings. So it's actually using a CLISC standard JUnit facility. So this is something I just found useful because I quite like to be able to run the test. And of course, if you've got Java, JUnit tests, it runs them all together. So it's just quite a nice way of integrating. And the same tests obviously will run with Maven if you're using JUnit integration or online test. So I found that quite useful. The one thing I haven't... Can you show an example of the test? Yeah, sure. So I tend to use the Maven layout. I find it's convenient when you work on Java code as well. So I have the test closure. I have a test colours. OK. So I'm testing some Java colours. I'm testing that. So it's a dev test. Who's really the closure of test? Most. OK. So closure of test is basically the unit testing library. It's pretty much... I think it's part of the core closure distribution now. So you get it basically out of the box. I'd say it's fairly primitive. It doesn't have simple assertions. It's good for just writing quick unit tests. And it's quite well understood and standard. And you basically write a dev test. So in this case, it's test-basic colours. You can give a little mini test suite inside if you want it just to be able to break up the test into smaller subcomponents. And it has this is macro, which just is asserting that the result of some expression is going to be true. And in this case, I want it to be true that white is 1.0, 1.0, 1.0, and black is 0.0, 0.0, 0.0. So that's the definition of the RGB colour vectors. And it's basically just writing normal closure namespace, test namespace, you write your dev tests, and then either CLJ unit or line test or maven test with the maven closure parking. We'll just pick up those tests and run them all as one integrated suite. Is it possible to run a single test? Yes, it is. So you can let me just test. I think it's a function. OK, so there's one old test. It drives everything. There is one test with namespace. So if I just want to test a particular namespace, say I just want to test in a particular namespace, which is kind of useful if you've got a big source file and you just want to test some module. No, I don't actually know what you can run a single test, but let's see what test colour actually is. I think I just switched to the namespace. So I couldn't press dot test core. Maybe this is loaded. OK, yeah. So, basically, because the test got run in a separate process when I was running a J unit test, it hadn't actually loaded this namespace, so I switched in the namespace, and it hadn't actually loaded the definitions at that point. So it's an object. I have no idea actually what it is. It was probably a way. Probably if you'd spec that object, you can figure out how to run it. Ultimately, I think down at its heart, it's just a function that's basically getting called by the test framework. I'm not sure how it's wrapped up. So they've wrapped it up in some kind of object here. But yes, I think you should be able to do that if you want to. The other thing I found quite useful on the testing front is test.check. And this is quite a nice tool. It does generative testing. So rather than just giving specific cases you want to test, you give it a set of properties that are thought to be true, so assertions, and some generators. So the generators actually generate your test cases. So you can generate vectors of different sizes, random strings, random maps of random strings, unless these generators together to actually build quite complicated random data structures. And what this will do is, it'll give you, you don't have to manually create all these test cases. 1,000 or 10,000 or how many of these you want it to write. And the other thing it does quite clever is shrinking. So if it finds a test failure, it will then shrink the case that failed and while it still fails, it tries to find the smallest possible failing test. Which is actually quite a cool feature because you don't necessarily want a 9,000 line test case. You want to find the smallest test case which actually demonstrates failing behaviour. So I'm not using this library but it's quite a nice testing method. And if you're smart using generators, you can actually get better test coverage for your lines of code. How do you decide what assertions to write? Because fundamentally your assertions are going to be validating, are going to be somewhat subject to the input, right? I mean certainly, how does it, I've had some understanding of that. So I'm not a big proponent to test different development. I write a code and then write a test. And I tend to write tests for things that I think I'm going to break later. So first of all I'll write some tests which validate that something is working. Anything at all. If something's working then it's mostly right. Then I'll write a test for some edge cases. Where I think if I change the code then maybe the case of an empty list might not work. So I try and write a couple of test cases around those corner points. And I write more tests if I think it's code that I'm likely to refactor. Because I find that that's actually one of the challenges testing closure code is whenever you're doing refactoring you haven't got a type checker to cover yourself. And you'll often find you introduce bugs when you're refactoring. So I write more tests when I think I'm going to do that. I say I'm not a big TDD practitioner. I write what the assertions would look like. Because ultimately what you're basically stating is you know what you're looking for and you're leaving it to the test generator. As I understand it, you're leaving it to the test generator to do the dirty work as far as exercising your functions. See if I can find an example. So this is a test in core.matrix using test.check And what it's doing is it's got this array generator which is generating it's actually a nested generator. So there's a generator for doubles so double numerical values. There's a generator for shapes of arrays. So it might be a 2 by 3 array or a 5 or a 10 times 9 times 7 times 6 4 dimensional array. So it generates shapes and increasingly large shapes as it builds them. And then it's got another generator which given a generator of shapes and a generator of array values builds larger and larger arrays after those shapes and values. So the array generator is basically this. It's going to create larger and larger numerical matrices. And what I'm saying is for property testing. So for all arrays which are produced by this array generator if the implementation supports that shape so if it's got the one kind of shape then it won't be testing it. But as long as you want a condition on which things you want to test but as long as the implementation supports that shape I want to run this function and I want to be sure that that function succeeds. Which is a test for that array instance. It's instant test is a bunch of separate assumptions. So test numeric assumptions for example. This is a presentation of the self. I want to keep you on the topic for a Senator workload job. So there's a bunch of tests which are basically nested inside these functions. The test there is different sub-properties of that array. Essentially I've got a question about the workload. Because you're looking at the outline is there any way that you can go into the definition declaration of the function like go into sort of, you know like so you've got a function like numeric scholar of tests is there a way that you put your part? You can navigate on this. You can navigate on this. Can you navigate this? I'm not sure there's a browse to to be honest. Navigate to definition F3. Is that going to work? It might be this is one of the things that doesn't work too well across names places. I don't know why that's not working. Oh, it's probably because I haven't loaded it. That looks more promising so I've actually got the dog strings and stuff. Mike, what kind of applications do you implement in this workbook? Is it generally libraries? I do libraries. I do sort of web applications, full-stat web applications, data processing code, machine learning code. I was going to demo from a workflow just something on the way that I've set up this for example. So what I find is very helpful is to have little helper functions so this is like a when doing for generated images. I tend to write little helper function that will actually display things or pop things up in a separate window. So if I want to show images that are generated by showing plotting the X and Y values it just opens up a little separate image. So I tend to use these little side windows to display but actually control everything from the wet wall. So I'm sort of using this as I use it as basically an interactive workbench as you're doing experiments and trying to build different kinds of tools. So what I'm generally doing is working at the wet wall and then when I found code that's useful I'm going to pop it into a source file or into a test case if I'm just testing things out. That's the way I find it's most helpful to work and if you use things like the reloaded pattern or fig wheel these kind of tools and you can do that kind of work and have things going on in the background and restarting web servers and compiling JavaScript and things like that. So once you've got it set up it works quite nicely. Sometimes a few fiddly bits just getting it started. Do you use debubbers? No, not really. I think there is some debubber support in here but I find that generally it's easier to actually figure out what's going on with tests rather than trying to step through a lot of code. And I don't think there is some debubber support and we can actually support breakpoints. I think it has got some support for debugging and breakpoints but I tend to do it through tests and through doing stuff in an exploratory manner on the wet wall. The other thing that's quite nice about this is it has both linogon and maven integration so you can use either of those to manage your projects, update dependencies all of these kind of things. From a workload perspective do you have a reference of maven versus linogon? I'm sort of indifferent I think that maven is sometimes convenient if you're working with Java stuff because the tools are better. So if I think I'm going to be doing a lot of releasing and CIE kind of stuff I probably have a slight reference to doing maven. On the other hand linogon has some features and some tools and some plugins that are quite handy if you're doing fig wheel stuff for specific closure things. And also linogon is people understand it better in the closure community so you're more likely to get people you're less likely to confuse people if you use project.clj. Now I personally think maven is actually not that bad I know that pop.xml is a pretty verbose but it does what it's meant to do and in a way linogon is just a nice pretty skin and a few extra features laid on top of the actual maven underlying model so I find them similar enough that you can sort of interchange. Closure itself you actually have to use pop.xml actually that's the official closure core policy is that closure-contrib libeys have to be maven-managed. I think that's because of all the build systems and CI and that kind of thing. Are there any new features in current model models and is it an active actively inventing and updated tool? Yeah definitely so it keeps on getting better every couple of months. There's a guy called Law and Petit who keeps on issuing new releases and I I find it does everything I've needed at least and certainly if you're an eclipse user I think it's natural to use counter-clockwise not saying it's better than all the other options but it certainly works for me. Are there any alternatives as far as if there's a plugin to go to counter-copper? Not because I'm aware of I think it's the only one for the best. It's a complex part we're not like humans we're a database and that is how you can see that we're a problem arts Well you mean in terms of So you gotta pat the problems Right.. Oh I think that's a job of warning Do you have something I think it does for things like if there's an error gweld i'r cyfnodau Llandon i'r cyfnodau Llywodraeth. Mae'n dweud maen nhw'n hynny oherwydd yn gweithio am gweithio'r gweithio ar gael de pens. Felly mae'r cyfnodau'r gweithio, ymgyrchu'r gweithio ar gael. Mae'n ddod yn ystod yn ei gweithio ar gael i'r cyfnodau. Mae'r gwaith yn llawer o'r ddweud y cyfrifagwyrn a'r ddweud yn gwneud y cyfrifagwyrn? Mae'r ddweud y cwestiynau. Roeddwn i amser yn y dweud yn y dweud am maen nhw'n cael bod'r cyfrifagwyrn. Roeddwn i amser o'r ddweud am maen nhw. Roeddwn i'n cael bod a'r ddweud am maen nhw'n cael bod'r cyfrifagwyrn yn gweithio wneud y ddweud ac yn cael bod mae'r cyfrifagwyrn eich bod yn cael ei dweud. I don't think it's got smart refactoring, like, you know, pull out arguments and that kind of thing. But I think those things are quite hard to do in Closure in general anyway, because you obviously haven't got the types. Like changing a function name or something like that, and then going through or changing out a function definition. Yeah, don't think it's really got that. But this stuff's quite hard to do in Closure, yeah, because you can define your function name programmatically. So there's no actual way that you can write an editor which actually can support total refactoring on Closure code. You know, you can always find ways of cheating, using some dynamism to cheat it and you can have code break. So unlike in a language where everything's like completely defined, you can actually find out every single reference to a bar, in Closure you can't do that because you can dynamically create those references to a bar. So it's a little bit trickier. How do you handle a situation like that when you need to make a change like that just to go through manually and sort of replace it? Well hopefully with at least one test that tests each code path. So at least that's going to fail if you rename something and it doesn't exist anymore. So that's probably your number one defence. You can do the usual search and replace stuff. Yeah, generally try and pick good names in Closure, so you don't have to refactor too much because it's actually my biggest bug barrier in Closure as refactoring is trickier than in some other languages. Particularly when you've got a large code base and a lot of cost links. I always do something stupid like change the name of a tag because I picked a bad name in the first place and then forget to update it in some other namespace assuming that this key is going to exist in this map. That's where a lot of the refactoring bugs I find come from. Any other questions? OK, great.