Using Emacs - 31 - elfeed part 3 - macros

In part 2 I talked about how I used Hyrdas to quickly navigate through elfeed tags. It was a nice step up but the fact that I still had to manually edit my configuration code for every new tag to update the hydra was a problem.

Basically, I had to somehow or other, take a list of all the active tags and with it build a defhydra command that will then make my Hydra.

Fortunately, emacs, being a lisp, has macros. I'm not talking about keyboard macros which I talked about in episode 15 but rather Lisp style macros. Macros let you transform code and then execute the transformed code.

The example I give in the video:

(defmacro infix (a op b)
  `(,op ,a ,b))

(infix 3 + 8) ; evaluates to 11

This transforms the 3+8 into (+ 3 8) and then evaluates it to be 11.

We can use this idea with our Hydra.

We can use the call elfeed-db-get-all-tags to get a list of all the tags in our database. I decided that if I had an uppercase letter in the tag, I'd use the lowercase version of that letter as my "hotkey" and if it didn't, I'd just use the first letter.

So, given a tag list of:

(active blogs cs eDucation emacs local misc sports star tech unread webcomics)

I'd want a "hotkey" of b for logs and d for eDucation.

The routine z/hasCap tests to see if a tag has a capital letter in it and z/get-hydra-option-key returns the final "hotkey:"

(defun z/hasCap (s) ""
       (let ((case-fold-search nil))
       (string-match-p "[[:upper:]]" s)
       ))


(defun z/get-hydra-option-key (s)
  "returns single upper case letter (converted to lower) or first"
  (interactive)
  (let ( (loc (z/hasCap s)))
    (if loc
	(downcase (substring s loc (+ loc 1)))
      (substring s 0 1)
    )))

mz/make-elfeed-cats takes a list of tags and returns a list of items where each item is in the form expected by the hydra definition:

("t" (elfeed-search-set-filter "@6-months-ago +tagname") "tagname")
(defun mz/make-elfeed-cats (tags)
  "Returns a list of lists. Each one is line for the hydra configuratio in the form
     (c function hint)"
  (interactive)
  (mapcar (lambda (tag)
	    (let* (
		   (tagstring (symbol-name tag))
		   (c (z/get-hydra-option-key tagstring))
		   )
	      (list c (append '(elfeed-search-set-filter) (list (format "@6-months-ago +%s" tagstring) ))tagstring  )))
	  tags))

Finally, here's our macro:

(defmacro mz/make-elfeed-hydra ()
  `(defhydra mz/hydra-elfeed ()
     "filter"
     ,@(mz/make-elfeed-cats (elfeed-db-get-all-tags))
     ("*" (elfeed-search-set-filter "@6-months-ago +star") "Starred")
     ("M" elfeed-toggle-star "Mark")
     ("A" (elfeed-search-set-filter "@6-months-ago") "All")
     ("T" (elfeed-search-set-filter "@1-day-ago") "Today")
     ("Q" bjm/elfeed-save-db-and-bury "Quit Elfeed" :color blue)
     ("q" nil "quit" :color blue)
     ))

The line that starts with *,@* calls the routine that builds lines of code for all the tags in the database and the macro leaves me with the defhydra I need.

I then redefine the hydra every time I need it, just in case tags changed:

(defun mz/make-and-run-elfeed-hydra ()
  ""
  (interactive)
  (mz/make-elfeed-hydra)
  (mz/hydra-elfeed/body))

and bind mz/make-and-run-elfeed-hydra to j and J in my elfeed keymap (this code goes in the bind section of my use-package elfeed section):

("j" . mz/make-and-run-elfeed-hydra)
("J" . mz/make-and-run-elfeed-hydra)

As long as I remember to name my tags in a way that they don't conflict with one another I can quickly navigate all around elfeed.

Macros FTW!!!!

Here's the video:

Enjoy.

Will we lose CS teachers to industry?

If we properly prepare CS teachers, won't they just jump ship and take tech industry jobs?

I hear that a lot.

Tech pays big. Teaching? Not so much. Tech workers are respected and have flexible jobs. Teaching? Again, not so much.

Those chanting these refrains advocate the current simple teacher "training" - scripted lessons, minimal pedagogical content knowledge, even less real content knowledge. That will keep them in the classroom.

They're wrong.

People fearing an exodus of prepared CS teachers don't get education. True, many young CS teachers will leave the profession but that's because many young teachers leave the profession. Why do young teachers leave? Regardless of subject area some of the reasons are:

  • It's much harder than everyone thinks it is
  • Low pay
  • Lack of respect
  • Overworked
  • Lack of autonomy
  • Being scapegoated for poverty
  • It's become about testing, not teaching

None of these are unique to computer science teachers so the argument that CS teachers who know too much will leave is really saying, "we have to keep our teachers dumb enough to stay - make sure they don't have outside options" rather than "let's make teaching a desirable profession to be in."

Of course, this is bred from a lack of understanding about what drives teachers. It's typical of politicians and business leaders and short term temps like TFAers who came in for a cup of coffee and now know how to solve the education problem.

Teacher don't become teachers to get rich or to do better than the other guy – I know I didn't. We enter it to do good - to uplift the have nots. This is why business models like stack ranking and bonus or merit pay just don't work. A school is a team and we're all in it together. Our job is to take care of our kids, not to be better than that other guy. We wish we had more time to work together and to improve things for our entire population.

Back to computer science.

My contention is that you might lose some teachers to industry but they either weren't meant to be teachers anyway or they couldn't afford to be teachers or the system beat them down. None of these are reasons not to properly prepare them. Besides, all teachers in all subject areas could work their way into an entry level tech job via a summer coding boot camp.

We can also look to the past to allay concerns. While it's true that for hiring purposes, English teachers are a dime a dozen and candidates typically have fewer outside options (although great English teachers are harder to find), Math and Science teachers generally have options. I know many top Math and Science teachers who could easily get non teaching jobs - the Math teachers in finance the science, certainly in pharmaceutical companies over in NJ. These options exist yet we manage to populate our classes with teachers. True, it's difficult at times, particularly in Physics, but these are due to the lack of respect teaching gets as a profession.

If we prepare CS teachers properly, yes, we'll lose some, but we'll keep the ones we're supposed to or if we lose them it will be due to other factors. Additionally, by having proper CS teacher preparation programs, we'll also provide an entry path to those people meant to be teachers but prior had no way of getting in.

As a nation, we're moving away from prepared, knowledgeable teachers and towards drill-masters. Let's not let CS Education go the way of all ed.

Using Emacs - 30 - elfeed part 2 - Hydras

In part 1, I talked about elfeed, a really awesome feed reader for emacs. Generally, I'm really liking it but there's been one problem - not being able to navigate quickly between groups of feeds with a keystroke or two.

It's emacs so there has to be a solution.

Enter hydra - a terrific emacs package from the same guy who brought us swiper, another one of my favorite emacs packages.

Basically, Hydra allows us to create Hydras - a collection of emacs commands tied o a single prefix along with a nice interface and help system.

Truth be told, I don't use hydra as much anymore since which-key does such a great job most of the time. Which-key, however, is no help here.

Here's the code to install hydra along with a some of sample Hydra's I use:

(use-package hydra 
  :ensure t)

;; Hydra for modes that toggle on and off
(global-set-key
 (kbd "C-x t")
 (defhydra toggle (:color blue)
   "toggle"
   ("a" abbrev-mode "abbrev")
   ("s" flyspell-mode "flyspell")
   ("d" toggle-debug-on-error "debug")
   ("c" fci-mode "fCi")
   ("f" auto-fill-mode "fill")
   ("t" toggle-truncate-lines "truncate")
   ("w" whitespace-mode "whitespace")
   ("q" nil "cancel")))

;; Hydra for navigation
(global-set-key
 (kbd "C-x j")
 (defhydra gotoline 
   ( :pre (linum-mode 1)
	  :post (linum-mode -1))
   "goto"
   ("t" (lambda () (interactive)(move-to-window-line-top-bottom 0)) "top")
   ("b" (lambda () (interactive)(move-to-window-line-top-bottom -1)) "bottom")
   ("m" (lambda () (interactive)(move-to-window-line-top-bottom)) "middle")
   ("e" (lambda () (interactive)(end-of-buffer)) "end")
   ("c" recenter-top-bottom "recenter")
   ("n" next-line "down")
   ("p" (lambda () (interactive) (forward-line -1))  "up")
   ("g" goto-line "goto-line")
   ))

;; Hydra for some org-mode stuff
(global-set-key
 (kbd "C-c t")
 (defhydra hydra-global-org (:color blue)
   "Org"
   ("t" org-timer-start "Start Timer")
   ("s" org-timer-stop "Stop Timer")
   ("r" org-timer-set-timer "Set Timer") ; This one requires you be in an orgmode doc, as it sets the timer for the header
   ("p" org-timer "Print Timer") ; output timer value to buffer
   ("w" (org-clock-in '(4)) "Clock-In") ; used with (org-clock-persistence-insinuate) (setq org-clock-persist t)
   ("o" org-clock-out "Clock-Out") ; you might also want (setq org-log-note-clock-out t)
   ("j" org-clock-goto "Clock Goto") ; global visit the clocked task
   ("c" org-capture "Capture") ; Don't forget to define the captures you want http://orgmode.org/manual/Capture.html
   ("l" (or )rg-capture-goto-last-stored "Last Capture"))

Take a look at the Hydra home page for detailed information.

With Hydra installed, I can creat one for navigating in elfeed:

`(defhydra mz/hydra-elfeed ()
   "filter"
   ("c" (elfeed-search-set-filter "@6-months-ago +cs") "cs")
   ("e" (elfeed-search-set-filter "@6-months-ago +emacs") "emacs")
   ("d" (elfeed-search-set-filter "@6-months-ago +education") "education")
   ("*" (elfeed-search-set-filter "@6-months-ago +star") "Starred")
   ("M" elfeed-toggle-star "Mark")
   ("A" (elfeed-search-set-filter "@6-months-ago") "All")
   ("T" (elfeed-search-set-filter "@1-day-ago") "Today")
   ("Q" bjm/elfeed-save-db-and-bury "Quit Elfeed" :color blue)
   ("q" nil "quit" :color blue)
   )

and add a binding to the elfeed key map:

(use-package elfeed
  :ensure t
  :bind (:map elfeed-search-mode-map
	      ("q" . bjm/elfeed-save-db-and-bury)
	      ("Q" . bjm/elfeed-save-db-and-bury)
	      ("m" . elfeed-toggle-star)
	      ("M" . elfeed-toggle-star)
	      ("j" . mz/hydra-elfeed/body)
	      ("J" . mz/hydra-elfeed/body)))

This isn't the actual Hydra I use – we'll get to that in the next installment where I'll show how to make a Hydra on the fly that contains keys for all your elfeed tags but this is a reasonable example.

Here's the video:

Enjoy.

Using Emacs - 29 -elfeed part 1

Since the demise of Google Reader, I've been using Feedly to read my streams. Feedly's a nice product and it's been working well for me for quite some time.

A few days ago, I decided to see what emacs had to offer on the feed reader front. One solution was Gnus but then I've never been able to get my head around Gnus. Another was elfeed.

I thought I'd give elfeed a go.

Combined with elfeed-goodies and elfeed-org it's a pretty nice solution. You can easily search by either keywords or tags and tags are particularly easy to set up with elfeed-org.

If I want to display all the items from the last month, I hit s (for search) and enter the query:

@6-months-ago

For only unread posts:

@6-months-ago +unread

For unread posts tagged emacs:

@6-months-ago +unread +emacs

And for everything in the past 24 hours, read or not:

@1-day-ago

It's pretty easy and pretty slick. The only thing missing is easy single key navigation. There's one solution to that problem over at Pragmatic Emacs and I'll present another one in the next two posts.

I'm using some of the code from pragmatic emacs (the functions that start with bjm) which makes things easier when sharing the elfeed database on Dropbox (see the Pragmatic Emacs post above for details) and also a couple of routines I found via web search).

Here's my basic configuration:

(setq elfeed-db-directory "~/Dropbox/shared/elfeeddb")


(defun elfeed-mark-all-as-read ()
      (interactive)
      (mark-whole-buffer)
      (elfeed-search-untag-all-unread))


;;functions to support syncing .elfeed between machines
;;makes sure elfeed reads index from disk before launching
(defun bjm/elfeed-load-db-and-open ()
  "Wrapper to load the elfeed db from disk before opening"
  (interactive)
  (elfeed-db-load)
  (elfeed)
  (elfeed-search-update--force))

;;write to disk when quiting
(defun bjm/elfeed-save-db-and-bury ()
  "Wrapper to save the elfeed db to disk before burying buffer"
  (interactive)
  (elfeed-db-save)
  (quit-window))



(defalias 'elfeed-toggle-star
  (elfeed-expose #'elfeed-search-toggle-all 'star))

(use-package elfeed
  :ensure t
  :bind (:map elfeed-search-mode-map
	      ("q" . bjm/elfeed-save-db-and-bury)
	      ("Q" . bjm/elfeed-save-db-and-bury)
	      ("m" . elfeed-toggle-star)
	      ("M" . elfeed-toggle-star)
	      )
  )

(use-package elfeed-goodies
  :ensure t
  :config
  (elfeed-goodies/setup))


(use-package elfeed-org
  :ensure t
  :config
  (elfeed-org)
  (setq rmh-elfeed-org-files (list "~/Dropbox/shared/elfeed.org")))

Check out elfeed and make sure to go to the links provided on the main elfeed page.

Enjoy.

Quality Devs and Coding Contests

I've been planning to put together a response to Alfred Thompson's recent post - Software Developers - Quantity vs Quality.

TL;DR, although it isn't really long and I do encourage you to read Alfred's post: a couple of articles talk about how the U.S. has the most people entering CS competitions like HackerRank but Americans are not at the top of the leaderboard. does this mean that there's less talent in America? Does it even matter?

Before getting to "does it matter," I looked over at the Kaggle leaderboards. Looking at their top 10, 2 were from the US - no other country had more than 1. The 11th placing competitor was also from the US and then 12 was from China, giving them 2 in the top 12. I also looked at recent IOI results and a quick glance seems to indicate that the USA seems to do reasonably well. In short, if you buy into ranking a country by these types of individual results on specific competitions then we're doing fine.

But, does filling the leaderboard mean a country's producing the best tech talent? Probably not.

Coding competitions focus on a specific skill set. There are problem solving aspects but they also require speed, knowledge of data structures and algorithms, and, yes, even accurate, fast typing skills. They also require you work alone. They don't encourage well designed, architected, or written code, working on existing code bases or working with a team.

Over the years, I've known some very smart and talented individuals who've excelled at these types of competitions. If you extend the pool to math and science competitions, I've known quite a few. These individuals have by and large done well for themselves but as a group, you couldn't call them more successful than any other subset of my former students. A number of them have gone on and are doing well as professors or programmers but, by and large, they're not the ones who've gone on to found companies and provide jobs for scores or even hundreds of other people and they're not necessarily the ones who've led teams that have developed major platforms and projects1

I don't argue that people who populate competition leaderboards are talented and a necessary part of our tech ecosystem but they're only a part. I probably want one of these programmers on my team, but not as the entire team (see Fake Grimlock's laws of startups - law 9).

Competitive programming is a piece of the puzzle as competitive programmers are a part of the population. So are project based events like Dream it. Code it. Win it., science fairs, and hackathons, which can be either cooperative, competitive, or a combination.

What do we want? Balance. I think the Stuy program does it pretty well. StuyCS graduates who wish to take part in coding competitions can do so but if they want to excel at it, they have to work at it on their own time. At the same time, the students learn how to work in teams and take a project from idea to delivery all the while learning some good academic CS and software engineering practices. They'll learn more in college on the academic side and the rest on the job. I'd love to see better balance in the colleges between CS programs preparing kids for graduate programs and CS programs that prepare kids for industry. I'd also love to see CS minors that were more targeted towards CS+X rather than half of a CS major targeting students going to grad schools.

I also think there's a tremendous opportunity for community colleges to fill the role currently occupied by code schools. They could more easily strike a balance between academic depth and practical preparation.

I'm working on building Hunter College's honors CS program and while I can't move the Hunter curriculum, I'm seeking that balance in my own way.

Will we get there? I don't know. Given the way education works, I figure at some point people will decide that we have to have more of a presence on the CS leaderboards and we'll see programs pop up with that in mind. I have no doubt that when that happens, we'll see many more Americans near the top. We have a large enough population that talent shouldn't be in question. This will be great for students to whom these competitions attract. It won't do much, however for the rest of the students. I'm not really concerned one way or another. Unlike math, where there's a natural progression through K12 math classes with math team and math competitions being a natural add on, the driving forces in CS - be they from industry, government, or academia don't seem to have partaken in any code competition Kool-Aid so code competitions won't become a driving force in CS ed any time soon.

Footnotes:

1

Some are but probably a smaller percent from that group than from the general pool.

Starting with scheme

Scheme is one of the languages used in Stuy's intro CS course. Like any other language, there are pros and cons of using it to introduce students to CS. Here are some of the reasons why I like Scheme as a first language and why despite that, I don't recommend it in many cases.

Scheme certainly isn't mainstream. That's not the main reason why I like it but it is a side benefit. It's less likely kids come into class knowing it which creates a level playing field. The few times I've had a student with a background in Scheme, they've been good, helpful kids rather than ones that tried to show off and dominate the class.

I like scheme because it's simple. It looks different than other languages but is (+ 3 4) really that different than add(3,4) or 3+4?

We can tell kids "everything's a function." While technically not true, and I tell my students that it isn't, it's close enough for our purposes. Everything's a function and the way we write a function is:

(f a b ...)

Apply function f on arguments b c …. So we have (+ 2 3) to add 2 and 3, (and a b) for logical and (= 3 4) to test to see if 3 is equal to 4, etc. We also have the same basic notation for things like conditionals. In java, we might write:

if (a > 5) {
 return 5;
} else {
  return 10;
}

In scheme, it would be:

(if (> a 5)
  5
  10)

Even though we're fudging the rules, we can lay out a handful of rules for the kids such as lambda and define follow a similar form to create and name functions:

(define add2 (lambda (a b) (+ a b)))

where (lambda (a b) (+ a b)) returns a function that adds a and b and define associates it with the identifier add2. Now we can use the function: (add2 5 10) which evaluates to 15.

With lambda, define, if, and a few more basics, it's off to the races. The simple, consistent syntax makes things easy for the kids and the constrained tool set lets us focus their way of thinking.

Of course this wouldn't work had DrScheme (now Racket) not existed. That gave us a nice learning IDE to work in.

Using Scheme, we can not only cover the basics like conditionals, abstraction and such but also deeper concepts like recursion, map, filter, and reduce. When we move on from Scheme, the kids also have a frame of reference for all the other languages and paradigms they use.

There are downsides, however. Outside help is harder to come by and there is some pushback from parents and it isn't as pretty and flashy as some other tool-sets. Scheme worked at Stuy for a number of reasons. When I created the class that used it, there were no good pre-AP classes in the school and I had a pretty good reputation as a teacher. The class also used multiple tools with NetLogo being the primary other one and tackled a variety of CS and non CS topics. First time through, reputation and buzz filled the classes and after that, the class developed a solid enough reputation to fill itself.

It also didn't hurt that our program developed from the inside out. First, we had APCS-AB on the books as a junior year course, then I added our post AP senior year electives. Since it was easy to show what the kids were already graduating with, it was easy to diffuse any pushback from not using mainstream tools in the first class.

Scheme worked at Stuy and I feel that it still does. Would I use Scheme for a first experience in a drop in program at an after-school where kids might not come back if they don't get to a payoff immediately? Probably not. Would I recommend it at a school where I want to integrate CS with some of the other subjects quickly, again, probably not (except for integration with algebra where Bootstrapworld is a terrific program).

In any event, if you're a high school CS teacher and haven't played with scheme or some other functional language, I highly recommend it - you might not actually ever teach it or use it but it can really help develop you as a programmer and an educator.

Selecting a starting language - why not Javascript

I was catching up with the team at Stuy the other day and they mentioned that they were periodically getting pushback on their choice of languages, particularly in the intro class. The pushback was mostly in the form of "why don't you start them with Javascript?"

Back in the day, when I created our intro class where we use Scheme, NetLogo and then later Python, I'd get similar pushback but then it was "why not Java?", "why not C?", or "whu not C++?"

We had a good discussion on this and I shared my thoughts as to why I don't like Javascript as a first language and I thought I'd share some of them here. I'll try to get around to the rationale behind Scheme and NetLogo in a later post.

To start, let me say that I Love Javascript - particularly when approaching it as a functional language. I also think every school and situation is different so there are likely times when Javascript is the right beginner language for the job.

Let's dive in.

Why are some of the pluses for Javascript as an intro language.

  • Ubiquity and availability:

    If you have a browser, you have Javascript - it's also available through online IDEs and online lightweight sites like JSFiddle.

  • Interactivity:

    You can tweak websites almost live, use the HTML5 canvas pretty interactively and mode

  • It's mainstream
  • It's quick to get up and running

This is all true, but there are also downsides.

One of my big problems with Javascript is the lack of simple solid educational tooling. I love to use tools like DrJava, DrPython, and Racket (formerly DrScheme) with beginners. All simple learning IDEs. True, you can use a simple online IDE but I haven't found them to have as strong a learning interface. They also, generally, keep you in an oversimplified programming sandbox. There's no clean transition from the sandbox to the real deal - particularly given the non-trivial state of js build tools and environments. These simple learning IDEs set the stage and then we can transition to more powerful development environments.

I also prefer, where possible, to have kids learn locally so that they can learn something about the underlying operating system even if only at a user level.

A problem relating to the lack of tooling is the fact that a JS program can fail to run and not give you any meaningful feedback at all - this is a problem for a beginner.

Javascript also has all sorts of wonkiness. We have =, and == which is pretty conventional, but then there's also ===. We have potentially confusing scoping issues and also some other real weirdness:

console.log(53-3); //  50
console.log(53-'3'); // 50
console.log('53'-3); // 50 
console.log('53'-'3'); //50

console.log(53+3); //  56
console.log(53+'3'); // '533'
console.log('53'+3); // '533
console.log('53'+'3'); // '533'

For more, check out the this video. Start watching at about 1:20 - it's a riot.

All of this weirdness actually makes sense - just not to a beginner.

Javascript also gives plenty of freedom - there are many ways to do things. This can be great for the developer but not necessarily ideal for the learner. Loops, recursion, mapping functions - you name it, Javascript's got it. I like simpler languages for beginners because it's easier to get them thinking and problem solving in certain ways when there tool set is somewhat restricted (more on that when I write about Scheme).

Finally, the fact that Javascript's a mainstream language can be a minus. Given its popularity, a beginner class could have at least a few kid who've at least played with the language. This can lead them to think they know more than they do and more importantly, this can be intimidating to the real newbies who develop the impression that "everyone knows this but me." A less mainstream language puts everyone on a level playing field.

Let me say again that I love javascript as a language and before a student graduates Stuy they can learn all about Javascript, front end development, some functional programming, and more. It's just not the right language to start with - at least not at Stuy.




Enter your email address:

Delivered by FeedBurner

Google Analytics Alternative